From c5650b0840ef1630ab9e67e9e314fb73ca112cdc Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 4 Feb 2007 23:52:02 -0500 Subject: [PATCH 1/5] bash: Support git-rebase -m continuation completion. Apparently `git-rebase -m` uses a metadata directory within .git (.git/.dotest-merge) rather than .dotest used by git-am (and git-rebase without the -m option). This caused the completion code to not offer --continue, --skip or --abort when working within a `git-rebase -m` session. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 430e6367a7..b0ff87d8d0 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -675,7 +675,7 @@ _git_push () _git_rebase () { local cur="${COMP_WORDS[COMP_CWORD]}" - if [ -d .dotest ]; then + if [ -d .dotest ] || [ -d .git/.dotest-merge ]; then __gitcomp "--continue --skip --abort" return fi From 88293c675c0c15c8247de32e903f4302bac63027 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 4 Feb 2007 23:52:08 -0500 Subject: [PATCH 2/5] bash: Complete git-remote subcommands. Completing the 3 core subcommands to git-remote, along with the names of remotes for 'show' and 'prune' (which take only existing remotes) is handy. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index b0ff87d8d0..eecdaa0e75 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -852,6 +852,32 @@ _git_config () " } +_git_remote () +{ + local i c=1 command + while [ $c -lt $COMP_CWORD ]; do + i="${COMP_WORDS[c]}" + case "$i" in + add|show|prune) command="$i"; break ;; + esac + c=$((++c)) + done + + if [ $c -eq $COMP_CWORD -a -z "$command" ]; then + __gitcomp "add show prune" + return + fi + + case "$command" in + show|prune) + __gitcomp "$(__git_remotes)" + ;; + *) + COMPREPLY=() + ;; + esac +} + _git_reset () { local cur="${COMP_WORDS[COMP_CWORD]}" @@ -934,6 +960,7 @@ _git () pull) _git_pull ;; push) _git_push ;; rebase) _git_rebase ;; + remote) _git_remote ;; reset) _git_reset ;; show) _git_show ;; show-branch) _git_log ;; @@ -979,6 +1006,7 @@ complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push complete -o default -o nospace -F _git_rebase git-rebase complete -o default -o nospace -F _git_config git-config +complete -o default -o nospace -F _git_remote git-remote complete -o default -o nospace -F _git_reset git-reset complete -o default -o nospace -F _git_show git-show complete -o default -o nospace -F _git_log git-show-branch From d46ae3f09a8c7b531e1110d46a2f8cdcfa853b11 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Mon, 5 Feb 2007 23:01:14 -0800 Subject: [PATCH 3/5] git-push: allow globbing wildcard refspec. This allows you to set up mothership-satellite configuration more symmetrically and naturally by allowing the globbing wildcard refspec for git-push. On your satellite machine: [remote "mothership"] url = mothership:project.git fetch = refs/heads/*:refs/remotes/mothership/* push = refs/heads/*:refs/remotes/satellite/* You would say "git fetch mothership" to update your tracking branches under mothership/ to keep track of the progress on the mothership side, and when you are done working on the satellite machine, you would "git push mothership" to update their tracking branches under satellite/. Corresponding configuration on the mothership machine can be used to make "git fetch satellite" update its tracking branch under satellite/. on the mothership. Signed-off-by: Junio C Hamano --- builtin-push.c | 114 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 32 deletions(-) diff --git a/builtin-push.c b/builtin-push.c index 5f4d7d34d3..c45649e26c 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -54,38 +54,84 @@ static void expand_refspecs(void) for_each_ref(expand_one_ref, NULL); } +struct wildcard_cb { + const char *from_prefix; + int from_prefix_len; + const char *to_prefix; + int to_prefix_len; + int force; +}; + +static int expand_wildcard_ref(const char *ref, const unsigned char *sha1, int flag, void *cb_data) +{ + struct wildcard_cb *cb = cb_data; + int len = strlen(ref); + char *expanded, *newref; + + if (len < cb->from_prefix_len || + memcmp(cb->from_prefix, ref, cb->from_prefix_len)) + return 0; + expanded = xmalloc(len * 2 + cb->force + + (cb->to_prefix_len - cb->from_prefix_len) + 2); + newref = expanded + cb->force; + if (cb->force) + expanded[0] = '+'; + memcpy(newref, ref, len); + newref[len] = ':'; + memcpy(newref + len + 1, cb->to_prefix, cb->to_prefix_len); + strcpy(newref + len + 1 + cb->to_prefix_len, + ref + cb->from_prefix_len); + add_refspec(expanded); + return 0; +} + +static int wildcard_ref(const char *ref) +{ + int len; + const char *colon; + struct wildcard_cb cb; + + memset(&cb, 0, sizeof(cb)); + if (ref[0] == '+') { + cb.force = 1; + ref++; + } + len = strlen(ref); + colon = strchr(ref, ':'); + if (! (colon && ref < colon && + colon[-2] == '/' && colon[-1] == '*' && + /* "/:/" is at least 7 bytes */ + 7 <= len && + ref[len-2] == '/' && ref[len-1] == '*') ) + return 0 ; + cb.from_prefix = ref; + cb.from_prefix_len = colon - ref - 1; + cb.to_prefix = colon + 1; + cb.to_prefix_len = len - (colon - ref) - 2; + for_each_ref(expand_wildcard_ref, &cb); + return 1; +} + static void set_refspecs(const char **refs, int nr) { if (nr) { - int pass; - for (pass = 0; pass < 2; pass++) { - /* pass 0 counts and allocates, pass 1 fills */ - int i, cnt; - for (i = cnt = 0; i < nr; i++) { - if (!strcmp("tag", refs[i])) { - int len; - char *tag; - if (nr <= ++i) - die("tag shorthand without "); - if (pass) { - len = strlen(refs[i]) + 11; - tag = xmalloc(len); - strcpy(tag, "refs/tags/"); - strcat(tag, refs[i]); - refspec[cnt] = tag; - } - cnt++; - continue; - } - if (pass) - refspec[cnt] = refs[i]; - cnt++; - } - if (!pass) { - size_t bytes = cnt * sizeof(char *); - refspec_nr = cnt; - refspec = xrealloc(refspec, bytes); + int i; + for (i = 0; i < nr; i++) { + const char *ref = refs[i]; + if (!strcmp("tag", ref)) { + char *tag; + int len; + if (nr <= ++i) + die("tag shorthand without "); + len = strlen(refs[i]) + 11; + tag = xmalloc(len); + strcpy(tag, "refs/tags/"); + strcat(tag, refs[i]); + ref = tag; } + else if (wildcard_ref(ref)) + continue; + add_refspec(ref); } } expand_refspecs(); @@ -129,8 +175,10 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI]) else error("more than %d URL's specified, ignoring the rest", MAX_URI); } - else if (is_refspec && !has_explicit_refspec) - add_refspec(xstrdup(s)); + else if (is_refspec && !has_explicit_refspec) { + if (!wildcard_ref(s)) + add_refspec(xstrdup(s)); + } } fclose(f); if (!n) @@ -156,8 +204,10 @@ static int get_remote_config(const char* key, const char* value) error("more than %d URL's specified, ignoring the rest", MAX_URI); } else if (config_get_refspecs && - !strcmp(key + 7 + config_repo_len, ".push")) - add_refspec(xstrdup(value)); + !strcmp(key + 7 + config_repo_len, ".push")) { + if (!wildcard_ref(value)) + add_refspec(xstrdup(value)); + } else if (config_get_receivepack && !strcmp(key + 7 + config_repo_len, ".receivepack")) { if (!receivepack) { From c8f80d4dc89eddd4b343cb82ca8a75cfa41f800e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 6 Feb 2007 01:09:32 -0800 Subject: [PATCH 4/5] gitweb: fix mismatched parenthesis An earlier commit 04179418 broke gitweb. Badly. Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index d374110070..653ca3cc60 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1963,7 +1963,7 @@ sub git_print_page_path { print "
"; print $cgi->a({-href => href(action=>"tree", hash_base=>$hb), - -title => 'tree root'}, to_utf8("[$project]"); + -title => 'tree root'}, to_utf8("[$project]")); print " / "; if (defined $name) { my @dirname = split '/', $name; From e68989a739d8b1c5effb898d1ac78d27ca9d313a Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 6 Feb 2007 01:52:04 -0800 Subject: [PATCH 5/5] annotate: fix for cvsserver. git-cvsserver does not want the boundary commits shown any differently. Signed-off-by: Junio C Hamano --- builtin-annotate.c | 2 +- builtin-blame.c | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/builtin-annotate.c b/builtin-annotate.c index 57c46840d5..9db7cfe74c 100644 --- a/builtin-annotate.c +++ b/builtin-annotate.c @@ -12,7 +12,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix) int i; nargv = xmalloc(sizeof(char *) * (argc + 2)); - nargv[0] = "blame"; + nargv[0] = "annotate"; nargv[1] = "-c"; for (i = 1; i < argc; i++) { diff --git a/builtin-blame.c b/builtin-blame.c index a18ef81a14..69fc145a38 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -41,6 +41,7 @@ static int max_score_digits; static int show_root; static int blank_boundary; static int incremental; +static int cmd_is_annotate; #ifndef DEBUG #define DEBUG 0 @@ -1554,12 +1555,12 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt) int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? 40 : 8; if (suspect->commit->object.flags & UNINTERESTING) { - if (!blank_boundary) { + if (blank_boundary) + memset(hex, ' ', length); + else if (!cmd_is_annotate) { length--; putchar('^'); } - else - memset(hex, ' ', length); } printf("%.*s", length, hex); @@ -2070,6 +2071,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix) const char *bottomtop = NULL; const char *contents_from = NULL; + cmd_is_annotate = !strcmp(argv[0], "annotate"); + git_config(git_blame_config); save_commit_buffer = 0;