diffcore-pickaxe.con commit Do a cross-project merge of Paul Mackerras' gitk visualizer (5569bf9)
   1/*
   2 * Copyright (C) 2005 Junio C Hamano
   3 */
   4#include "cache.h"
   5#include "diff.h"
   6#include "diffcore.h"
   7
   8static int contains(struct diff_filespec *one,
   9                    const char *needle, unsigned long len)
  10{
  11        unsigned long offset, sz;
  12        const char *data;
  13        if (diff_populate_filespec(one, 0))
  14                return 0;
  15        sz = one->size;
  16        data = one->data;
  17        for (offset = 0; offset + len <= sz; offset++)
  18                     if (!strncmp(needle, data + offset, len))
  19                             return 1;
  20        return 0;
  21}
  22
  23void diffcore_pickaxe(const char *needle, int opts)
  24{
  25        struct diff_queue_struct *q = &diff_queued_diff;
  26        unsigned long len = strlen(needle);
  27        int i, has_changes;
  28        struct diff_queue_struct outq;
  29        outq.queue = NULL;
  30        outq.nr = outq.alloc = 0;
  31
  32        if (opts & DIFF_PICKAXE_ALL) {
  33                /* Showing the whole changeset if needle exists */
  34                for (i = has_changes = 0; !has_changes && i < q->nr; i++) {
  35                        struct diff_filepair *p = q->queue[i];
  36                        if (!DIFF_FILE_VALID(p->one)) {
  37                                if (!DIFF_FILE_VALID(p->two))
  38                                        continue; /* ignore unmerged */
  39                                /* created */
  40                                if (contains(p->two, needle, len))
  41                                        has_changes++;
  42                        }
  43                        else if (!DIFF_FILE_VALID(p->two)) {
  44                                if (contains(p->one, needle, len))
  45                                        has_changes++;
  46                        }
  47                        else if (!diff_unmodified_pair(p) &&
  48                                 contains(p->one, needle, len) !=
  49                                 contains(p->two, needle, len))
  50                                has_changes++;
  51                }
  52                if (has_changes)
  53                        return; /* not munge the queue */
  54
  55                /* otherwise we will clear the whole queue
  56                 * by copying the empty outq at the end of this
  57                 * function, but first clear the current entries
  58                 * in the queue.
  59                 */
  60                for (i = 0; i < q->nr; i++)
  61                        diff_free_filepair(q->queue[i]);
  62        }
  63        else 
  64                /* Showing only the filepairs that has the needle */
  65                for (i = 0; i < q->nr; i++) {
  66                        struct diff_filepair *p = q->queue[i];
  67                        has_changes = 0;
  68                        if (!DIFF_FILE_VALID(p->one)) {
  69                                if (!DIFF_FILE_VALID(p->two))
  70                                        ; /* ignore unmerged */
  71                                /* created */
  72                                else if (contains(p->two, needle, len))
  73                                        has_changes = 1;
  74                        }
  75                        else if (!DIFF_FILE_VALID(p->two)) {
  76                                if (contains(p->one, needle, len))
  77                                        has_changes = 1;
  78                        }
  79                        else if (!diff_unmodified_pair(p) &&
  80                                 contains(p->one, needle, len) !=
  81                                 contains(p->two, needle, len))
  82                                has_changes = 1;
  83
  84                        if (has_changes)
  85                                diff_q(&outq, p);
  86                        else
  87                                diff_free_filepair(p);
  88                }
  89
  90        free(q->queue);
  91        *q = outq;
  92        return;
  93}