So that it's possible to remove certain refs from the list without removing the objects that are referenced by other refs. For example this repository: * 374e8dd (crap) crap * 4cbbf7b (test) two * d025ae0 (HEAD, master) one When using '--branches --except crap': * 4cbbf7b (test) two * d025ae0 (HEAD, master) one But when using '--branches --not crap' nothing will come out. Signed-off-by: Felipe Contreras <felipe.contreras@xxxxxxxxx> --- Documentation/git-rev-parse.txt | 6 ++++++ contrib/completion/git-completion.bash | 2 +- revision.c | 10 ++++++++++ revision.h | 3 ++- t/t6112-rev-list-except.sh | 35 ++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100755 t/t6112-rev-list-except.sh diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 2b126c0..fe5cc6b 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -110,6 +110,12 @@ can be used. strip '{caret}' prefix from the object names that already have one. +--except:: + Skip the following object names. For example: + '--branches --except master' will show all the branches, except master. + This differs from --not in that --except will still show the object, if + they are referenced by another object name. + --symbolic:: Usually the object names are output in SHA-1 form (with possible '{caret}' prefix); this option makes them output in a diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 5da920e..aed8c12 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1386,7 +1386,7 @@ _git_ls_tree () # Options that go well for log, shortlog and gitk __git_log_common_options=" - --not --all + --not --except --all --branches --tags --remotes --first-parent --merges --no-merges --max-count= diff --git a/revision.c b/revision.c index 84ccc05..375adab 100644 --- a/revision.c +++ b/revision.c @@ -1984,6 +1984,8 @@ static int handle_revision_pseudo_opt(const char *submodule, handle_reflog(revs, *flags); } else if (!strcmp(arg, "--not")) { *flags ^= UNINTERESTING | BOTTOM; + } else if (!strcmp(arg, "--except")) { + *flags ^= SKIP; } else if (!strcmp(arg, "--no-walk")) { revs->no_walk = REVISION_WALK_NO_WALK_SORTED; } else if (!prefixcmp(arg, "--no-walk=")) { @@ -2578,6 +2580,7 @@ int prepare_revision_walk(struct rev_info *revs) int nr = revs->pending.nr; struct object_array_entry *e, *list; struct commit_list **next = &revs->commits; + int i; e = list = revs->pending.objects; revs->pending.nr = 0; @@ -2585,12 +2588,19 @@ int prepare_revision_walk(struct rev_info *revs) revs->pending.objects = NULL; while (--nr >= 0) { struct commit *commit = handle_commit(revs, e->item, e->name); + for (i = 0; i < revs->cmdline.nr; i++) { + struct rev_cmdline_entry *ce; + ce = &revs->cmdline.rev[i]; + if ((ce->flags & SKIP) && !strcmp(ce->name, e->name)) + goto next; + } if (commit) { if (!(commit->object.flags & SEEN)) { commit->object.flags |= SEEN; next = commit_list_append(commit, next); } } +next: e++; } if (!revs->leak_pending) diff --git a/revision.h b/revision.h index 95859ba..89f5037 100644 --- a/revision.h +++ b/revision.h @@ -17,7 +17,8 @@ #define SYMMETRIC_LEFT (1u<<8) #define PATCHSAME (1u<<9) #define BOTTOM (1u<<10) -#define ALL_REV_FLAGS ((1u<<11)-1) +#define SKIP (1u<<11) +#define ALL_REV_FLAGS ((1u<<12)-1) #define DECORATE_SHORT_REFS 1 #define DECORATE_FULL_REFS 2 diff --git a/t/t6112-rev-list-except.sh b/t/t6112-rev-list-except.sh new file mode 100755 index 0000000..b8f9a61 --- /dev/null +++ b/t/t6112-rev-list-except.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='test for rev-list --except' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + echo one > content && + git add content && + git commit -m one && + git checkout -b test master && + echo two > content && + git commit -a -m two && + git checkout -b merge master && + git merge test +' + +test_expect_success 'rev-list --except' ' + + git rev-list --topo-order --branches --except merge > actual && + git rev-list --topo-order test > expect && + test_cmp expect actual +' + +test_expect_success 'rev-list --except with extra' ' + + echo three > content && + git commit -a -m three && + git rev-list --topo-order --branches --except merge > actual && + git rev-list --topo-order test > expect && + test_cmp expect actual +' + +test_done -- 1.8.4-fc -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html