Merge branch 'maint' into HEAD
authorJunio C Hamano <gitster@pobox.com>
Wed, 31 Oct 2007 04:44:43 +0000 (21:44 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 31 Oct 2007 04:44:43 +0000 (21:44 -0700)
* maint:
Update GIT 1.5.3.5 Release Notes
git-rebase--interactive.sh: Make 3-way merge strategies work for -p.
git-rebase--interactive.sh: Don't pass a strategy to git-cherry-pick.
Fix --strategy parsing in git-rebase--interactive.sh
Make merge-recursive honor diff.renamelimit
cherry-pick/revert: more compact user direction message
core-tutorial: Use new syntax for git-merge.
git-merge: document but discourage the historical syntax
Prevent send-pack from segfaulting (backport from 'master')
Documentation/git-cvsexportcommit.txt: s/mgs/msg/ in example

Conflicts:

git-rebase--interactive.sh

1  2 
Documentation/core-tutorial.txt
Documentation/git-merge.txt
builtin-revert.c
git-rebase--interactive.sh
index d8e78ac8f15013a5db9c8918723d3ee2850fe43e,df147b5e76879851a5a95f4ddb9695786f042d56..5df97a1f9d5633657e4aad05a39acbf0d09e4a58
@@@ -553,8 -553,13 +553,8 @@@ can explore on your own
  
  [NOTE]
  Most likely, you are not directly using the core
 -git Plumbing commands, but using Porcelain like Cogito on top
 -of it. Cogito works a bit differently and you usually do not
 -have to run `git-update-index` yourself for changed files (you
 -do tell underlying git about additions and removals via
 -`cg-add` and `cg-rm` commands). Just before you make a commit
 -with `cg-commit`, Cogito figures out which files you modified,
 -and runs `git-update-index` on them for you.
 +git Plumbing commands, but using Porcelain such as `git-add`, `git-rm'
 +and `git-commit'.
  
  
  Tagging a version
@@@ -681,8 -686,8 +681,8 @@@ $ git rese
  
  and in fact a lot of the common git command combinations can be scripted
  with the `git xyz` interfaces.  You can learn things by just looking
 -at what the various git scripts do.  For example, `git reset` is the
 -above two lines implemented in `git-reset`, but some things like
 +at what the various git scripts do.  For example, `git reset` used to be
 +the above two lines implemented in `git-reset`, but some things like
  `git status` and `git commit` are slightly more complex scripts around
  the basic git commands.
  
@@@ -800,8 -805,8 +800,8 @@@ you have, you can sa
  $ git branch
  ------------
  
 -which is nothing more than a simple script around `ls .git/refs/heads`.
 -There will be asterisk in front of the branch you are currently on.
 +which used to be nothing more than a simple script around `ls .git/refs/heads`.
 +There will be an asterisk in front of the branch you are currently on.
  
  Sometimes you may wish to create a new branch _without_ actually
  checking it out and switching to it. If so, just use the command
@@@ -878,7 -883,7 +878,7 @@@ script called `git merge`, which wants 
  to resolve and what the merge is all about:
  
  ------------
- $ git merge "Merge work in mybranch" HEAD mybranch
+ $ git merge -m "Merge work in mybranch" mybranch
  ------------
  
  where the first argument is going to be used as the commit message if
@@@ -947,7 -952,7 +947,7 @@@ the later output lines is used to show 
  `master` branch, and the second column for the `mybranch`
  branch. Three commits are shown along with their log messages.
  All of them have non blank characters in the first column (`*`
 -shows an ordinary commit on the current branch, `.` is a merge commit), which
 +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
@@@ -965,7 -970,7 +965,7 @@@ to the `master` branch. Let's go back t
  
  ------------
  $ git checkout mybranch
- $ git merge "Merge upstream changes." HEAD master
+ $ git merge -m "Merge upstream changes." master
  ------------
  
  This outputs something like this (the actual commit object names
@@@ -1081,7 -1086,7 +1081,7 @@@ to help dumb transport downloaders
  There are (confusingly enough) `git-ssh-fetch` and `git-ssh-upload`
  programs, which are 'commit walkers'; they outlived their
  usefulness when git Native and SSH transports were introduced,
 -and not used by `git pull` or `git push` scripts.
 +and are not used by `git pull` or `git push` scripts.
  
  Once you fetch from the remote repository, you `merge` that
  with your current branch.
@@@ -1188,7 -1193,7 +1188,7 @@@ $ mb=$(git-merge-base HEAD mybranch
  
  The command writes the commit object name of the common ancestor
  to the standard output, so we captured its output to a variable,
 -because we will be using it in the next step.  BTW, the common
 +because we will be using it in the next step.  By the way, the common
  ancestor commit is the "New day." commit in this case.  You can
  tell it by:
  
@@@ -1454,7 -1459,8 +1454,7 @@@ Although git is a truly distributed sys
  convenient to organize your project with an informal hierarchy
  of developers. Linux kernel development is run this way. There
  is a nice illustration (page 17, "Merges to Mainline") in
 -link:http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf
 -[Randy Dunlap's presentation].
 +link:http://www.xenotime.net/linux/mentor/linux-mentoring-2006.pdf[Randy Dunlap's presentation].
  
  It should be stressed that this hierarchy is purely *informal*.
  There is nothing fundamental in git that enforces the "chain of
@@@ -1607,8 -1613,8 +1607,8 @@@ in both of them.  You could merge in 'd
  'commit-fix' next, like this:
  
  ------------
- $ git merge 'Merge fix in diff-fix' master diff-fix
- $ git merge 'Merge fix in commit-fix' master commit-fix
+ $ git merge -m 'Merge fix in diff-fix' diff-fix
+ $ git merge -m 'Merge fix in commit-fix' commit-fix
  ------------
  
  Which would result in:
index bca4212e565c95f79a76a14cc4444e72e472a22c,827838f7d05e21875c9843fd782c4ade1a8b141e..eabd7ef33f6c01322fc3794341c8982573b516a4
@@@ -11,26 -11,27 +11,27 @@@ SYNOPSI
  [verse]
  'git-merge' [-n] [--summary] [--no-commit] [--squash] [-s <strategy>]...
        [-m <msg>] <remote> <remote>...
+ 'git-merge' <msg> HEAD <remote>...
  
  DESCRIPTION
  -----------
  This is the top-level interface to the merge machinery
  which drives multiple merge strategy scripts.
  
+ The second syntax (<msg> `HEAD` <remote>) is supported for
+ historical reasons.  Do not use it from the command line or in
+ new scripts.  It is the same as `git merge -m <msg> <remote>`.
  
  OPTIONS
  -------
  include::merge-options.txt[]
  
- <msg>::
-m <msg>::
        The commit message to be used for the merge commit (in case
        it is created). The `git-fmt-merge-msg` script can be used
        to give a good default for automated `git-merge` invocations.
  
- <head>::
-       Our branch head commit.  This has to be `HEAD`, so new
-       syntax does not require it
  <remote>::
        Other branch head merged into our branch.  You need at
        least one <remote>.  Specifying more than one <remote>
@@@ -58,10 -59,6 +59,10 @@@ merge.verbosity:
        above outputs debugging information.  The default is level 2.
        Can be overridden by 'GIT_MERGE_VERBOSITY' environment variable.
  
 +branch.<name>.mergeoptions::
 +      Sets default options for merging into branch <name>. The syntax and
 +      supported options are equal to that of git-merge, but option values
 +      containing whitespace characters are currently not supported.
  
  HOW MERGE WORKS
  ---------------
diff --combined builtin-revert.c
index a655c8ee2ab25ef778b182fbd5ff298a732c1cfd,eafafbc333e784aa2c49ee9d360077cb212797c6..e855b206cf030c5e907d94b171fbbfe3b9601a2b
@@@ -168,7 -168,9 +168,7 @@@ static void set_author_ident_env(const 
                        char *line, *pend, *email, *timestamp;
  
                        p += 7;
 -                      line = xmalloc(eol + 1 - p);
 -                      memcpy(line, p, eol - p);
 -                      line[eol - p] = '\0';
 +                      line = xmemdupz(p, eol - p);
                        email = strchr(line, '<');
                        if (!email)
                                die ("Could not extract author email from %s",
@@@ -349,7 -351,7 +349,7 @@@ static int revert_or_cherry_pick(int ar
                        die ("Error wrapping up %s", defmsg);
                fprintf(stderr, "Automatic %s failed.  "
                        "After resolving the conflicts,\n"
-                       "mark the corrected paths with 'git-add <paths>'\n"
+                       "mark the corrected paths with 'git add <paths>' "
                        "and commit the result.\n", me);
                if (action == CHERRY_PICK) {
                        fprintf(stderr, "When commiting, use the option "
index 0dd77b4005b9d80bfe6c606954d7666df77abc57,f28c3df204214f691de87cb48c513f1eb5d767e6..76dc679e62cf32a5ba04902558812e3244baf936
@@@ -36,14 -36,14 +36,14 @@@ warn () 
  output () {
        case "$VERBOSE" in
        '')
 -              "$@" > "$DOTEST"/output 2>&1
 +              output=$("$@" 2>&1 )
                status=$?
 -              test $status != 0 &&
 -                      cat "$DOTEST"/output
 +              test $status != 0 && printf "%s\n" "$output"
                return $status
 -      ;;
 +              ;;
        *)
                "$@"
 +              ;;
        esac
  }
  
@@@ -63,7 -63,6 +63,7 @@@ comment_for_reflog () 
        ''|rebase*)
                GIT_REFLOG_ACTION="rebase -i ($1)"
                export GIT_REFLOG_ACTION
 +              ;;
        esac
  }
  
@@@ -71,23 -70,22 +71,23 @@@ mark_action_done () 
        sed -e 1q < "$TODO" >> "$DONE"
        sed -e 1d < "$TODO" >> "$TODO".new
        mv -f "$TODO".new "$TODO"
 -      count=$(($(wc -l < "$DONE")))
 -      total=$(($count+$(wc -l < "$TODO")))
 +      count=$(($(grep -ve '^$' -e '^#' < "$DONE" | wc -l)))
 +      total=$(($count+$(grep -ve '^$' -e '^#' < "$TODO" | wc -l)))
        printf "Rebasing (%d/%d)\r" $count $total
        test -z "$VERBOSE" || echo
  }
  
  make_patch () {
 -      parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null)
 +      parent_sha1=$(git rev-parse --verify "$1"^) ||
 +              die "Cannot get patch for $1^"
        git diff-tree -p "$parent_sha1".."$1" > "$DOTEST"/patch
 +      test -f "$DOTEST"/message ||
 +              git cat-file commit "$1" | sed "1,/^$/d" > "$DOTEST"/message
 +      test -f "$DOTEST"/author-script ||
 +              get_author_ident_from_commit "$1" > "$DOTEST"/author-script
  }
  
  die_with_patch () {
 -      test -f "$DOTEST"/message ||
 -              git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message
 -      test -f "$DOTEST"/author-script ||
 -              get_author_ident_from_commit $sha1 > "$DOTEST"/author-script
        make_patch "$1"
        die "$2"
  }
@@@ -97,26 -95,21 +97,26 @@@ die_abort () 
        die "$1"
  }
  
 +has_action () {
 +      grep -vqe '^$' -e '^#' "$1"
 +}
 +
  pick_one () {
        no_ff=
        case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
        output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
        test -d "$REWRITTEN" &&
                pick_one_preserving_merges "$@" && return
 -      parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
 +      parent_sha1=$(git rev-parse --verify $sha1^) ||
 +              die "Could not get the parent of $sha1"
        current_sha1=$(git rev-parse --verify HEAD)
 -      if test $no_ff$current_sha1 = $parent_sha1; then
 +      if test "$no_ff$current_sha1" = "$parent_sha1"; then
                output git reset --hard $sha1
                test "a$1" = a-n && output git reset --soft $current_sha1
                sha1=$(git rev-parse --short $sha1)
                output warn Fast forward to $sha1
        else
-               output git cherry-pick $STRATEGY "$@"
+               output git cherry-pick "$@"
        fi
  }
  
@@@ -136,7 -129,7 +136,7 @@@ pick_one_preserving_merges () 
        fast_forward=t
        preserve=t
        new_parents=
 -      for p in $(git rev-list --parents -1 $sha1 | cut -d -f2-)
 +      for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
        do
                if test -f "$REWRITTEN"/$p
                then
                                ;; # do nothing; that parent is already there
                        *)
                                new_parents="$new_parents $new_p"
 +                              ;;
                        esac
                fi
        done
        case $fast_forward in
        t)
                output warn "Fast forward to $sha1"
 -              test $preserve=f && echo $sha1 > "$REWRITTEN"/$sha1
 +              test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1
                ;;
        f)
                test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
  
 -              first_parent=$(expr "$new_parents" : " \([^ ]*\)")
 +              first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
                # detach HEAD to current parent
                output git checkout $first_parent 2> /dev/null ||
                        die "Cannot move HEAD to $first_parent"
  
                echo $sha1 > "$DOTEST"/current-commit
                case "$new_parents" in
 -              \ *\ *)
 +              ' '*' '*)
                        # redo merge
                        author_script=$(get_author_ident_from_commit $sha1)
                        eval "$author_script"
 -                      msg="$(git cat-file commit $sha1 | \
 -                              sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")"
 +                      msg="$(git cat-file commit $sha1 | sed -e '1,/^$/d')"
+                       # No point in merging the first parent, that's HEAD
+                       new_parents=${new_parents# $first_parent}
                        # NEEDSWORK: give rerere a chance
 -                      if ! output git merge $STRATEGY -m "$msg" $new_parents
 +                      if ! GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
 +                              GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
 +                              GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
 +                              output git merge $STRATEGY -m "$msg" \
 +                                      $new_parents
                        then
 -                              echo "$msg" > "$GIT_DIR"/MERGE_MSG
 +                              printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
                                die Error redoing merge $sha1
                        fi
                        ;;
                *)
-                       output git cherry-pick $STRATEGY "$@" ||
+                       output git cherry-pick "$@" ||
                                die_with_patch $sha1 "Could not pick $sha1"
 +                      ;;
                esac
 +              ;;
        esac
  }
  
@@@ -225,28 -214,27 +227,28 @@@ peek_next_command () 
  }
  
  do_next () {
 -      test -f "$DOTEST"/message && rm "$DOTEST"/message
 -      test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
 +      rm -f "$DOTEST"/message "$DOTEST"/author-script \
 +              "$DOTEST"/amend || exit
        read command sha1 rest < "$TODO"
        case "$command" in
 -      \#|'')
 +      '#'*|'')
                mark_action_done
                ;;
 -      pick)
 +      pick|p)
                comment_for_reflog pick
  
                mark_action_done
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
                ;;
 -      edit)
 +      edit|e)
                comment_for_reflog edit
  
                mark_action_done
                pick_one $sha1 ||
                        die_with_patch $sha1 "Could not apply $sha1... $rest"
                make_patch $sha1
 +              : > "$DOTEST"/amend
                warn
                warn "You can amend the commit now, with"
                warn
                warn
                exit 0
                ;;
 -      squash)
 +      squash|s)
                comment_for_reflog squash
  
 -              test -z "$(grep -ve '^$' -e '^#' < $DONE)" &&
 +              has_action "$DONE" ||
                        die "Cannot 'squash' without a previous commit"
  
                mark_action_done
                make_squash_message $sha1 > "$MSG"
                case "$(peek_next_command)" in
 -              squash)
 +              squash|s)
                        EDIT_COMMIT=
                        USE_OUTPUT=output
                        cp "$MSG" "$SQUASH_MSG"
 -              ;;
 +                      ;;
                *)
                        EDIT_COMMIT=-e
                        USE_OUTPUT=
 -                      test -f "$SQUASH_MSG" && rm "$SQUASH_MSG"
 +                      rm -f "$SQUASH_MSG" || exit
 +                      ;;
                esac
  
                failed=f
                f)
                        # This is like --amend, but with a different message
                        eval "$author_script"
 -                      export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
 +                      GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
 +                      GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
 +                      GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
                        $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
                        ;;
                t)
                        warn
                        warn "Could not apply $sha1... $rest"
                        die_with_patch $sha1 ""
 +                      ;;
                esac
                ;;
        *)
                warn "Unknown command: $command $sha1 $rest"
                die_with_patch $sha1 "Please fix this in the file $TODO."
 +              ;;
        esac
        test -s "$TODO" && return
  
        else
                NEWHEAD=$(git rev-parse HEAD)
        fi &&
 -      message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
 -      git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
 -      git symbolic-ref HEAD $HEADNAME && {
 +      case $HEADNAME in
 +      refs/*)
 +              message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
 +              git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
 +              git symbolic-ref HEAD $HEADNAME
 +              ;;
 +      esac && {
                test ! -f "$DOTEST"/verbose ||
                        git diff-tree --stat $(cat "$DOTEST"/head)..HEAD
        } &&
        rm -rf "$DOTEST" &&
 +      git gc --auto &&
        warn "Successfully rebased and updated $HEADNAME."
  
        exit
@@@ -354,9 -332,7 +356,9 @@@ d
                git update-index --refresh &&
                git diff-files --quiet &&
                ! git diff-index --cached --quiet HEAD &&
 -              . "$DOTEST"/author-script &&
 +              . "$DOTEST"/author-script && {
 +                      test ! -f "$DOTEST"/amend || git reset --soft HEAD^
 +              } &&
                export GIT_AUTHOR_NAME GIT_AUTHOR_NAME GIT_AUTHOR_DATE &&
                git commit -F "$DOTEST"/message -e
  
  
                HEADNAME=$(cat "$DOTEST"/head-name)
                HEAD=$(cat "$DOTEST"/head)
 -              git symbolic-ref HEAD $HEADNAME &&
 +              case $HEADNAME in
 +              refs/*)
 +                      git symbolic-ref HEAD $HEADNAME
 +                      ;;
 +              esac &&
                output git reset --hard $HEAD &&
                rm -rf "$DOTEST"
                exit
                output git reset --hard && do_rest
                ;;
        -s|--strategy)
-               shift
                case "$#,$1" in
                *,*=*)
                        STRATEGY="-s `expr "z$1" : 'z-[^=]*=\(.*\)'`" ;;
  
                require_clean_work_tree
  
 -              mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
                if test ! -z "$2"
                then
                        output git show-ref --verify --quiet "refs/heads/$2" ||
                HEAD=$(git rev-parse --verify HEAD) || die "No HEAD?"
                UPSTREAM=$(git rev-parse --verify "$1") || die "Invalid base"
  
 +              mkdir "$DOTEST" || die "Could not create temporary $DOTEST"
 +
                test -z "$ONTO" && ONTO=$UPSTREAM
  
                : > "$DOTEST"/interactive || die "Could not mark as interactive"
 -              git symbolic-ref HEAD > "$DOTEST"/head-name ||
 -                      die "Could not get HEAD"
 +              git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
 +                      echo "detached HEAD" > "$DOTEST"/head-name
  
                echo $HEAD > "$DOTEST"/head
                echo $UPSTREAM > "$DOTEST"/upstream
@@@ -499,18 -469,17 +500,18 @@@ EO
                        $UPSTREAM...$HEAD | \
                        sed -n "s/^>/pick /p" >> "$TODO"
  
 -              test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
 +              has_action "$TODO" ||
                        die_abort "Nothing to do"
  
                cp "$TODO" "$TODO".backup
                git_editor "$TODO" ||
                        die "Could not execute editor"
  
 -              test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
 +              has_action "$TODO" ||
                        die_abort "Nothing to do"
  
                output git checkout $ONTO && do_rest
 +              ;;
        esac
        shift
  done