From: Junio C Hamano Date: Sun, 15 Jan 2006 09:19:09 +0000 (-0800) Subject: Merge branches 'jc/checkout', 'jc/format-patch', 'jc/octopus', 'jc/sb' and 'jc/clone' X-Git-Tag: v1.2.0~143 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=d425142e2a045a9dd7879d028ec68bd748df48a3;hp=980d8ce551784b76e05077946b8a4f2ac6c5305d;p=git.git Merge branches 'jc/checkout', 'jc/format-patch', 'jc/octopus', 'jc/sb' and 'jc/clone' --- diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 790b87b2..8488202e 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -9,7 +9,7 @@ git-clone - Clones a repository. SYNOPSIS -------- [verse] -'git-clone' [-l [-s]] [-q] [-n] [-o ] [-u ] +'git-clone' [-l [-s]] [-q] [-n] [--naked] [-o ] [-u ] [] DESCRIPTION @@ -58,6 +58,12 @@ OPTIONS -n:: No checkout of HEAD is performed after the clone is complete. +--naked:: + Make a 'naked' GIT repository. That is, instead of + creating `` and placing the administrative + files in `/.git`, make the `` + itself the `$GIT_DIR`. This implies `-n` option. + -o :: Instead of using the branch name 'origin' to keep track of the upstream repository, use instead. Note @@ -103,6 +109,22 @@ $ cd copy $ git show-branch ------------ + +Create a naked repository to publish your changes to the public:: ++ +------------ +$ git clone --naked -l /home/proj/.git /pub/scm/proj.git +------------ + + +Create a repository on the kernel.org machine that borrows from Linus:: ++ +------------ +$ git clone --naked -l -s /pub/scm/.../torvalds/linux-2.6.git \ + /pub/scm/.../me/subsys-2.6.git +------------ + + Author ------ Written by Linus Torvalds diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.txt index 5b76f3b9..7b1a9c98 100644 --- a/Documentation/git-show-branch.txt +++ b/Documentation/git-show-branch.txt @@ -7,7 +7,10 @@ git-show-branch - Show branches and their commits. SYNOPSIS -------- -'git-show-branch [--all] [--heads] [--tags] [--topo-order] [--more= | --list | --independent | --merge-base] [--no-name | --sha1-name] [ | ]...' +[verse] +git-show-branch [--all] [--heads] [--tags] [--topo-order] [--current] + [--more= | --list | --independent | --merge-base] + [--no-name | --sha1-name] [ | ]... DESCRIPTION ----------- @@ -18,6 +21,9 @@ and/or $GIT_DIR/refs/tags) semi-visually. It cannot show more than 29 branches and commits at a time. +It uses `showbranch.default` multi-valued configuration items if +no nor is given on the command line. + OPTIONS ------- @@ -35,6 +41,11 @@ OPTIONS Show all refs under $GIT_DIR/refs, $GIT_DIR/refs/heads, and $GIT_DIR/refs/tags, respectively. +--current:: + With this option, the command includes the current + branch to the list of revs to be shown when it is not + given on the command line. + --topo-order:: By default, the branches and their commits are shown in reverse chronological order. This option makes them @@ -50,7 +61,7 @@ OPTIONS tree. --list:: - Synomym to `--more=-1` + Synonym to `--more=-1` --merge-base:: Instead of showing the commit list, just act like the @@ -78,13 +89,14 @@ OUTPUT ------ Given N , the first N lines are the one-line description from their commit message. The branch head that is -pointed at by $GIT_DIR/HEAD is prefixed with an asterisk '*' -character while other heads are prefixed with a '!' character. +pointed at by $GIT_DIR/HEAD is prefixed with an asterisk `*` +character while other heads are prefixed with a `!` character. Following these N lines, one-line log for each commit is displayed, indented N places. If a commit is on the I-th -branch, the I-th indentation character shows a '+' sign; -otherwise it shows a space. Each commit shows a short name that +branch, the I-th indentation character shows a `+` sign; +otherwise it shows a space. Merge commits are denoted by +a `-` sign. Each commit shows a short name that can be used as an extended SHA1 to name that commit. The following example shows three branches, "master", "fixes" @@ -92,7 +104,7 @@ and "mhf": ------------------------------------------------ $ git show-branch master fixes mhf -! [master] Add 'git show-branch'. +* [master] Add 'git show-branch'. ! [fixes] Introduce "reset type" flag to "git reset" ! [mhf] Allow "+remote:local" refspec to cause --force when fetching. --- @@ -106,13 +118,33 @@ $ git show-branch master fixes mhf + [mhf~6] Retire git-parse-remote. + [mhf~7] Multi-head fetch. + [mhf~8] Start adding the $GIT_DIR/remotes/ support. -+++ [master] Add 'git show-branch'. +*++ [master] Add 'git show-branch'. ------------------------------------------------ These three branches all forked from a common commit, [master], whose commit message is "Add 'git show-branch'. "fixes" branch adds one commit 'Introduce "reset type"'. "mhf" branch has many -other commits. +other commits. The current branch is "master". + + +EXAMPLE +------- + +If you keep your primary branches immediately under +`$GIT_DIR/refs/heads`, and topic branches in subdirectories of +it, having the following in the configuration file may help: + +------------ +[showbranch] + default = --topo-order + default = heads/* + +------------ + +With this,`git show-branch` without extra parameters would show +only the primary branches. In addition, if you happen to be on +your topic branch, it is shown as well. + Author diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt index 5a7e0cfe..d10476b5 100644 --- a/Documentation/howto/revert-branch-rebase.txt +++ b/Documentation/howto/revert-branch-rebase.txt @@ -32,16 +32,16 @@ merge introduced 5 commits or so: ------------------------------------------------ $ git show-branch --more=4 master master^2 | head -! [master] Merge refs/heads/portable from http://www.cs.berkeley.... +* [master] Merge refs/heads/portable from http://www.cs.berkeley.... ! [master^2] Replace C99 array initializers with code. -- -+ [master] Merge refs/heads/portable from http://www.cs.berkeley.... -++ [master^2] Replace C99 array initializers with code. -++ [master^2~1] Replace unsetenv() and setenv() with older putenv(). -++ [master^2~2] Include sys/time.h in daemon.c. -++ [master^2~3] Fix ?: statements. -++ [master^2~4] Replace zero-length array decls with []. -+ [master~1] tutorial note about git branch +- [master] Merge refs/heads/portable from http://www.cs.berkeley.... +*+ [master^2] Replace C99 array initializers with code. +*+ [master^2~1] Replace unsetenv() and setenv() with older putenv(). +*+ [master^2~2] Include sys/time.h in daemon.c. +*+ [master^2~3] Fix ?: statements. +*+ [master^2~4] Replace zero-length array decls with []. +* [master~1] tutorial note about git branch ------------------------------------------------ The '--more=4' above means "after we reach the merge base of refs, @@ -193,8 +193,8 @@ $ git show-branch --more=1 master pu rc + [pu~4] Document "git cherry-pick" and "git revert" + [pu~5] Remove git-apply-patch-script. + [pu~6] Redo "revert" using three-way merge machinery. - + [rc] Merge refs/heads/master from . -+++ [master] Revert "Replace zero-length array decls with []." - + [rc~1] Merge refs/heads/master from . -+++ [master~1] Merge refs/heads/portable from http://www.cs.berkeley.... + - [rc] Merge refs/heads/master from . +++* [master] Revert "Replace zero-length array decls with []." + - [rc~1] Merge refs/heads/master from . +... [master~1] Merge refs/heads/portable from http://www.cs.berkeley.... ------------------------------------------------ diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt index edd91cbb..b8fa2999 100644 --- a/Documentation/tutorial.txt +++ b/Documentation/tutorial.txt @@ -968,8 +968,8 @@ $ git show-branch master mybranch * [master] Merge work in mybranch ! [mybranch] Some work. -- -+ [master] Merge work in mybranch -++ [mybranch] Some work. +- [master] Merge work in mybranch +*+ [mybranch] Some work. ------------------------------------------------ The first two lines indicate that it is showing the two branches @@ -979,7 +979,8 @@ top-of-the-tree commits, you are currently on `master` branch the later output lines is used to show commits contained in the `master` branch, and the second column for the `mybranch` branch. Three commits are shown along with their log messages. -All of them have plus `+` characters in the first column, which +All of them have non blank characters in the first column (`*` +shows an ordinary commit on the current branch, `.` is a merge commit), which means they are now part of the `master` branch. Only the "Some work" commit has the plus `+` character in the second column, because `mybranch` has not been merged to incorporate these @@ -1024,7 +1025,7 @@ $ git show-branch master mybranch ! [master] Merge work in mybranch * [mybranch] Merge work in mybranch -- -++ [master] Merge work in mybranch +-- [master] Merge work in mybranch ------------------------------------------------ @@ -1199,9 +1200,9 @@ $ git show-branch --more=3 master mybranch ! [master] Merge work in mybranch * [mybranch] Merge work in mybranch -- -++ [master] Merge work in mybranch -++ [master^2] Some work. -++ [master^] Some fun. +-- [master] Merge work in mybranch ++* [master^2] Some work. ++* [master^] Some fun. ------------ Remember, before running `git merge`, our `master` head was at @@ -1223,8 +1224,8 @@ $ git show-branch ! [mybranch] Some work. -- + [mybranch] Some work. -+ [master] Some fun. -++ [mybranch^] New day. +* [master] Some fun. +*+ [mybranch^] New day. ------------ Now we are ready to experiment with the merge by hand. @@ -1743,8 +1744,8 @@ $ git show-branch + [diff-fix] Fix rename detection. + [diff-fix~1] Better common substring algorithm. + [commit-fix] Fix commit message normalization. - + [master] Release candidate #1 -+++ [diff-fix~2] Pretty-print messages. + * [master] Release candidate #1 +++* [diff-fix~2] Pretty-print messages. ------------ Both fixes are tested well, and at this point, you want to merge @@ -1764,13 +1765,13 @@ $ git show-branch ! [diff-fix] Fix rename detection. * [master] Merge fix in commit-fix --- - + [master] Merge fix in commit-fix -+ + [commit-fix] Fix commit message normalization. - + [master~1] Merge fix in diff-fix - ++ [diff-fix] Fix rename detection. - ++ [diff-fix~1] Better common substring algorithm. - + [master~2] Release candidate #1 -+++ [master~3] Pretty-print messages. + - [master] Merge fix in commit-fix ++ * [commit-fix] Fix commit message normalization. + - [master~1] Merge fix in diff-fix + +* [diff-fix] Fix rename detection. + +* [diff-fix~1] Better common substring algorithm. + * [master~2] Release candidate #1 +++* [master~3] Pretty-print messages. ------------ However, there is no particular reason to merge in one branch @@ -1797,12 +1798,12 @@ $ git show-branch ! [diff-fix] Fix rename detection. * [master] Octopus merge of branches 'diff-fix' and 'commit-fix' --- - + [master] Octopus merge of branches 'diff-fix' and 'commit-fix' -+ + [commit-fix] Fix commit message normalization. - ++ [diff-fix] Fix rename detection. - ++ [diff-fix~1] Better common substring algorithm. - + [master~1] Release candidate #1 -+++ [master~2] Pretty-print messages. + - [master] Octopus merge of branches 'diff-fix' and 'commit-fix' ++ * [commit-fix] Fix commit message normalization. + +* [diff-fix] Fix rename detection. + +* [diff-fix~1] Better common substring algorithm. + * [master~1] Release candidate #1 +++* [master~2] Pretty-print messages. ------------ Note that you should not do Octopus because you can. An octopus diff --git a/git-clone.sh b/git-clone.sh index 377d59e6..168eb963 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -9,7 +9,7 @@ unset CDPATH usage() { - echo >&2 "Usage: $0 [-l [-s]] [-q] [-u ] [-o ] [-n] []" + echo >&2 "Usage: $0 [--naked] [-l [-s]] [-q] [-u ] [-o ] [-n] []" exit 1 } @@ -53,11 +53,15 @@ use_local=no local_shared=no no_checkout= upload_pack= +naked= origin=origin while case "$#,$1" in 0,*) break ;; - *,-n) no_checkout=yes ;; + *,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\ + *,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout) + no_checkout=yes ;; + *,--na|*,--nak|*,--nake|*,--naked) naked=yes ;; *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local) use_local=yes ;; *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) local_shared=yes; use_local=yes ;; @@ -81,6 +85,9 @@ do shift done +# --naked implies --no-checkout +test -z "$naked" || no_checkout=yes + # Turn the source into an absolute path if # it is local repo="$1" @@ -95,10 +102,17 @@ dir="$2" [ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*/||g') [ -e "$dir" ] && echo "$dir already exists." && usage mkdir -p "$dir" && -D=$( - (cd "$dir" && git-init-db && pwd) -) && -test -d "$D" || usage +D=$(cd "$dir" && pwd) && +case "$naked" in +yes) GIT_DIR="$D" ;; +*) GIT_DIR="$D/.git" ;; +esac && export GIT_DIR && git-init-db || usage +case "$naked" in +yes) + GIT_DIR="$D" ;; +*) + GIT_DIR="$D/.git" ;; +esac # We do local magic only when the user tells us to. case "$local,$use_local" in @@ -118,21 +132,21 @@ yes,yes) test -f "$repo/$sample_file" || exit l= - if ln "$repo/$sample_file" "$D/.git/objects/sample" 2>/dev/null + if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null then l=l fi && - rm -f "$D/.git/objects/sample" && + rm -f "$GIT_DIR/objects/sample" && cd "$repo" && - find objects -depth -print | cpio -puamd$l "$D/.git/" || exit 1 + find objects -depth -print | cpio -puamd$l "$GIT_DIR/" || exit 1 ;; yes) - mkdir -p "$D/.git/objects/info" + mkdir -p "$GIT_DIR/objects/info" { test -f "$repo/objects/info/alternates" && cat "$repo/objects/info/alternates"; echo "$repo/objects" - } >"$D/.git/objects/info/alternates" + } >"$GIT_DIR/objects/info/alternates" ;; esac @@ -143,27 +157,27 @@ yes,yes) HEAD=HEAD fi (cd "$repo" && tar cf - refs $HEAD) | - (cd "$D/.git" && tar xf -) || exit 1 + (cd "$GIT_DIR" && tar xf -) || exit 1 ;; *) case "$repo" in rsync://*) rsync $quiet -av --ignore-existing \ - --exclude info "$repo/objects/" "$D/.git/objects/" && + --exclude info "$repo/objects/" "$GIT_DIR/objects/" && rsync $quiet -av --ignore-existing \ - --exclude info "$repo/refs/" "$D/.git/refs/" || exit + --exclude info "$repo/refs/" "$GIT_DIR/refs/" || exit # Look at objects/info/alternates for rsync -- http will # support it natively and git native ones will do it on the # remote end. Not having that file is not a crime. rsync -q "$repo/objects/info/alternates" \ - "$D/.git/TMP_ALT" 2>/dev/null || - rm -f "$D/.git/TMP_ALT" - if test -f "$D/.git/TMP_ALT" + "$GIT_DIR/TMP_ALT" 2>/dev/null || + rm -f "$GIT_DIR/TMP_ALT" + if test -f "$GIT_DIR/TMP_ALT" then ( cd "$D" && . git-parse-remote && - resolve_alternates "$repo" <"./.git/TMP_ALT" ) | + resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) | while read alt do case "$alt" in 'bad alternate: '*) die "$alt";; esac @@ -171,9 +185,9 @@ yes,yes) '') echo >&2 "Getting alternate: $alt" ;; esac rsync $quiet -av --ignore-existing \ - --exclude info "$alt" "$D/.git/objects" || exit + --exclude info "$alt" "$GIT_DIR/objects" || exit done - rm -f "$D/.git/TMP_ALT" + rm -f "$GIT_DIR/TMP_ALT" fi ;; http://*) @@ -194,25 +208,25 @@ esac cd "$D" || exit -if test -f ".git/HEAD" +if test -f "$GIT_DIR/HEAD" then head_points_at=`git-symbolic-ref HEAD` case "$head_points_at" in refs/heads/*) head_points_at=`expr "$head_points_at" : 'refs/heads/\(.*\)'` - mkdir -p .git/remotes && - echo >.git/remotes/origin \ + mkdir -p "$GIT_DIR/remotes" && + echo >"$GIT_DIR/remotes/origin" \ "URL: $repo Pull: $head_points_at:$origin" && git-update-ref "refs/heads/$origin" $(git-rev-parse HEAD) && - find .git/refs/heads -type f -print | + (cd "$GIT_DIR" && find "refs/heads" -type f -print) | while read ref do - head=`expr "$ref" : '.git/refs/heads/\(.*\)'` && + head=`expr "$ref" : 'refs/heads/\(.*\)'` && test "$head_points_at" = "$head" || test "$origin" = "$head" || echo "Pull: ${head}:${head}" - done >>.git/remotes/origin + done >>"$GIT_DIR/remotes/origin" esac case "$no_checkout" in diff --git a/git-format-patch.sh b/git-format-patch.sh index d3979d76..7e67c4e4 100755 --- a/git-format-patch.sh +++ b/git-format-patch.sh @@ -34,14 +34,12 @@ outdir=./ while case "$#" in 0) break;; esac do case "$1" in - -a|--a|--au|--aut|--auth|--autho|--author) - author=t ;; -c|--c|--ch|--che|--chec|--check) check=t ;; - -d|--d|--da|--dat|--date) - date=t ;; - -m|--m|--mb|--mbo|--mbox) - date=t author=t mbox=t ;; + -a|--a|--au|--aut|--auth|--autho|--author|\ + -d|--d|--da|--dat|--date|\ + -m|--m|--mb|--mbo|--mbox) # now noop + ;; -k|--k|--ke|--kee|--keep|--keep-|--keep-s|--keep-su|--keep-sub|\ --keep-subj|--keep-subje|--keep-subjec|--keep-subject) keep_subject=t ;; @@ -173,80 +171,89 @@ titleScript=' q ' -whosepatchScript=' -/^author /{ - s/'\''/'\''\\'\'\''/g - s/author \(.*>\) \(.*\)$/au='\''\1'\'' ad='\''\2'\''/p - q -}' - process_one () { - mailScript=' - /./d - /^$/n' - case "$keep_subject" in - t) ;; - *) - mailScript="$mailScript"' - s|^\[PATCH[^]]*\] *|| - s|^|[PATCH'"$num"'] |' - ;; - esac - mailScript="$mailScript"' - s|^|Subject: |' - case "$mbox" in - t) - echo 'From nobody Mon Sep 17 00:00:00 2001' ;# UNIX "From" line - ;; - esac + perl -w -e ' +my ($keep_subject, $num, $signoff, $commsg) = @ARGV; +my ($signoff_pattern, $done_header, $done_subject, $signoff_seen, + $last_was_signoff); - eval "$(sed -ne "$whosepatchScript" $commsg)" - test "$author,$au" = ",$me" || { - mailScript="$mailScript"' - a\ -From: '"$au" - } - test "$date,$au" = ",$me" || { - mailScript="$mailScript"' - a\ -Date: '"$ad" - } +if ($signoff) { + $signoff = `git-var GIT_COMMITTER_IDENT`; + $signoff =~ s/>.*/>/; + $signoff_pattern = quotemeta($signoff); +} - mailScript="$mailScript"' - a\ +my @weekday_names = qw(Sun Mon Tue Wed Thu Fri Sat); +my @month_names = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); - : body - p - n - b body' +sub show_date { + my ($time, $tz) = @_; + my $minutes = abs($tz); + $minutes = ($minutes / 100) * 60 + ($minutes % 100); + if ($tz < 0) { + $minutes = -$minutes; + } + my $t = $time + $minutes * 60; + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime($t); + return sprintf("%s %s %d %02d:%02d:%02d %d %+05d", + $weekday_names[$wday], + $month_names[$mon], + $mday, $hour, $min, $sec, + $year+1900, $tz); +} - (cat $commsg ; echo; echo) | - sed -ne "$mailScript" | - git-stripspace +print "From nobody Mon Sep 17 00:00:00 2001\n"; +open FH, "git stripspace <$commsg |" or die "open $commsg pipe"; +while () { + unless ($done_header) { + if (/^$/) { + $done_header = 1; + } + elsif (/^author (.*>) (.*)$/) { + my ($author_ident, $author_date) = ($1, $2); + my ($utc, $off) = ($author_date =~ /^(\d+) ([-+]?\d+)$/); + $author_date = show_date($utc, $off); - test "$signoff" = "t" && { - offsigner=`git-var GIT_COMMITTER_IDENT | sed -e 's/>.*/>/'` - line="Signed-off-by: $offsigner" - grep -q "^$line\$" $commsg || { - echo - echo "$line" - echo - } + print "From: $author_ident\n"; + print "Date: $author_date\n"; } - echo - echo '---' - echo + next; + } + unless ($done_subject) { + unless ($keep_subject) { + s/^\[PATCH[^]]*\]\s*//; + s/^/[PATCH$num] /; + } + print "Subject: $_"; + $done_subject = 1; + next; + } + + $last_was_signoff = 0; + if (/Signed-off-by:/i) { + if ($signoff ne "" && /Signed-off-by:\s*$signoff_pattern$/i) { + $signoff_seen = 1; + } + } + print $_; +} +if (!$signoff_seen && $signoff ne "") { + if (!$last_was_signoff) { + print "\n"; + } + print "$signoff\n"; +} +print "\n---\n\n"; +close FH or die "close $commsg pipe"; +' "$keep_subject" "$num" "$signoff" $commsg + git-diff-tree -p $diff_opts "$commit" | git-apply --stat --summary echo git-diff-tree -p $diff_opts "$commit" echo "-- " echo "@@GIT_VERSION@@" - case "$mbox" in - t) - echo - ;; - esac + echo } total=`wc -l <$series | tr -dc "[0-9]"` diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index d1f9f3d2..eb74f96e 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -48,8 +48,19 @@ MRC=$head MSG= PARENT="-p $head" MRT=$(git-write-tree) CNT=1 ;# counting our head NON_FF_MERGE=0 +OCTOPUS_FAILURE=0 for SHA1 in $remotes do + case "$OCTOPUS_FAILURE" in + 1) + # We allow only last one to have a hand-resolvable + # conflicts. Last round failed and we still had + # a head to merge. + echo "Automated merge did not work." + echo "Should not be doing an Octopus." + exit 2 + esac + common=$(git-merge-base --all $MRC $SHA1) || die "Unable to find common commit with $SHA1" @@ -84,11 +95,8 @@ do if test $? -ne 0 then echo "Simple merge did not work, trying automatic merge." - git-merge-index -o git-merge-one-file -a || { - echo "Not trivially merged." - echo "Should not be doing an Octopus." - exit 2 - } + git-merge-index -o git-merge-one-file -a || + OCTOPUS_FAILURE=1 next=$(git-write-tree 2>/dev/null) fi @@ -103,4 +111,4 @@ do MRT=$next done -exit 0 +exit "$OCTOPUS_FAILURE" diff --git a/show-branch.c b/show-branch.c index f1bce499..7a0dcc64 100644 --- a/show-branch.c +++ b/show-branch.c @@ -5,7 +5,7 @@ #include "refs.h" static const char show_branch_usage[] = -"git-show-branch [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [...]"; +"git-show-branch [--current] [--all] [--heads] [--tags] [--topo-order] [--more=count | --list | --independent | --merge-base ] [...]"; static int default_num = 0; static int default_alloc = 0; @@ -435,12 +435,12 @@ static void snarf_refs(int head, int tag) } } -static int rev_is_head(char *head_path, int headlen, - char *name, +static int rev_is_head(char *head_path, int headlen, char *name, unsigned char *head_sha1, unsigned char *sha1) { int namelen; - if ((!head_path[0]) || memcmp(head_sha1, sha1, 20)) + if ((!head_path[0]) || + (head_sha1 && sha1 && memcmp(head_sha1, sha1, 20))) return 0; namelen = strlen(name); if ((headlen < namelen) || @@ -545,6 +545,8 @@ int main(int ac, char **av) int sha1_name = 0; int shown_merge_point = 0; int topo_order = 0; + int with_current_branch = 0; + int head_at = -1; git_config(git_show_branch_config); setup_git_directory(); @@ -573,6 +575,8 @@ int main(int ac, char **av) extra = -1; else if (!strcmp(arg, "--no-name")) no_name = 1; + else if (!strcmp(arg, "--current")) + with_current_branch = 1; else if (!strcmp(arg, "--sha1-name")) sha1_name = 1; else if (!strncmp(arg, "--more=", 7)) @@ -604,6 +608,34 @@ int main(int ac, char **av) ac--; av++; } + head_path_p = resolve_ref(git_path("HEAD"), head_sha1, 1); + if (head_path_p) { + head_path_len = strlen(head_path_p); + memcpy(head_path, head_path_p, head_path_len + 1); + } + else { + head_path_len = 0; + head_path[0] = 0; + } + + if (with_current_branch && head_path_p) { + int has_head = 0; + for (i = 0; !has_head && i < ref_name_cnt; i++) { + /* We are only interested in adding the branch + * HEAD points at. + */ + if (rev_is_head(head_path, + head_path_len, + ref_name[i], + head_sha1, NULL)) + has_head++; + } + if (!has_head) { + int pfxlen = strlen(git_path("refs/heads/")); + append_one_rev(head_path + pfxlen); + } + } + if (!ref_name_cnt) { fprintf(stderr, "No revs to be shown.\n"); exit(0); @@ -639,16 +671,6 @@ int main(int ac, char **av) if (0 <= extra) join_revs(&list, &seen, num_rev, extra); - head_path_p = resolve_ref(git_path("HEAD"), head_sha1, 1); - if (head_path_p) { - head_path_len = strlen(head_path_p); - memcpy(head_path, head_path_p, head_path_len + 1); - } - else { - head_path_len = 0; - head_path[0] = 0; - } - if (merge_base) return show_merge_base(seen, num_rev); @@ -675,6 +697,8 @@ int main(int ac, char **av) } /* header lines never need name */ show_one_commit(rev[i], 1); + if (is_head) + head_at = i; } if (0 <= extra) { for (i = 0; i < num_rev; i++) @@ -703,9 +727,19 @@ int main(int ac, char **av) shown_merge_point |= ((this_flag & all_revs) == all_revs); if (1 < num_rev) { - for (i = 0; i < num_rev; i++) - putchar((this_flag & (1u << (i + REV_SHIFT))) - ? '+' : ' '); + int is_merge = !!(commit->parents && commit->parents->next); + for (i = 0; i < num_rev; i++) { + int mark; + if (!(this_flag & (1u << (i + REV_SHIFT)))) + mark = ' '; + else if (is_merge) + mark = '-'; + else if (i == head_at) + mark = '*'; + else + mark = '+'; + putchar(mark); + } putchar(' '); } show_one_commit(commit, no_name); diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index d7562e97..8ff5dd92 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -118,8 +118,8 @@ cat > show-branch.expect << EOF * [master] Merged "mybranch" changes. ! [mybranch] Some work. -- -+ [master] Merged "mybranch" changes. -++ [mybranch] Some work. +- [master] Merged "mybranch" changes. +*+ [mybranch] Some work. EOF git show-branch --topo-order master mybranch > show-branch.output @@ -142,7 +142,7 @@ cat > show-branch2.expect << EOF ! [master] Merged "mybranch" changes. * [mybranch] Merged "mybranch" changes. -- -++ [master] Merged "mybranch" changes. +-- [master] Merged "mybranch" changes. EOF git show-branch --topo-order master mybranch > show-branch2.output