Merge with http://www.kernel.org/pub/scm/git/git.git
authorPeter Anvin <hpa@tazenda.sc.orionmulti.com>
Thu, 29 Sep 2005 06:20:08 +0000 (23:20 -0700)
committerPeter Anvin <hpa@tazenda.sc.orionmulti.com>
Thu, 29 Sep 2005 06:20:08 +0000 (23:20 -0700)
16 files changed:
.gitignore
fsck-objects.c
git-applypatch.sh
git-commit.sh
git-fetch.sh
git-fmt-merge-msg.perl
git-merge.sh
git-octopus.sh
git-parse-remote.sh
git-pull.sh
git-rebase.sh
git-reset.sh
git-resolve.sh
http-fetch.c
t/t1000-read-tree-m-3way.sh
update-ref.c
index 145690f622979967174197d9de542bbd76f4fcea..c3eb9543ff2b8a2fcd0c9e48cbd9f9faf83f711d 100644 (file)
@@ -25,6 +25,7 @@ git-diff-stages
 git-diff-tree
 git-fetch
 git-fetch-pack
+git-fmt-merge-msg
 git-format-patch
 git-fsck-objects
 git-get-tar-commit-id
@@ -86,6 +87,7 @@ git-tar-tree
 git-unpack-file
 git-unpack-objects
 git-update-index
+git-update-ref
 git-update-server-info
 git-upload-pack
 git-var
index b82685fd718b0269bee4153badd391e9218a2b29..247edf052900e22c958595f34b7bce886c369377 100644 (file)
@@ -30,7 +30,7 @@ static void objreport(struct object *obj, const char *severity,
        fputs("\n", stderr);
 }
 
-int objerror(struct object *obj, const char *err, ...)
+static int objerror(struct object *obj, const char *err, ...)
 {
        va_list params;
        va_start(params, err);
@@ -39,7 +39,7 @@ int objerror(struct object *obj, const char *err, ...)
        return -1;
 }
 
-int objwarning(struct object *obj, const char *err, ...)
+static int objwarning(struct object *obj, const char *err, ...)
 {
        va_list params;
        va_start(params, err);
index fd594ed4e48a1aee7f4e9c0a6bbb3a44f1bb2120..9f5a45bb2bbb330207ea4410a76f5521bdc7b850 100755 (executable)
@@ -108,9 +108,10 @@ fi
 
 tree=$(git-write-tree) || exit 1
 echo Wrote tree $tree
-commit=$(git-commit-tree $tree -p $(cat "$GIT_DIR"/HEAD) < "$final") || exit 1
+parent=$(git-rev-parse --verify HEAD) &&
+commit=$(git-commit-tree $tree -p $parent <"$final") || exit 1
 echo Committed: $commit
-echo $commit > "$GIT_DIR"/HEAD
+git-update-ref HEAD $commit $parent || exit
 
 if test -x "$GIT_DIR"/hooks/post-applypatch
 then
index 18ad36158dad5a2fc542cb9c1daf65b32ba5b4a3..18b259c7086224f70cfd69798dc6332df040a61d 100755 (executable)
@@ -159,7 +159,9 @@ if [ ! -r "$GIT_DIR/HEAD" ]; then
                exit 1
        fi
        PARENTS=""
+       current=
 else
+       current=$(git-rev-parse --verify HEAD)
        if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
                PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
        fi
@@ -220,7 +222,7 @@ if test -s .cmitchk
 then
        tree=$(git-write-tree) &&
        commit=$(cat .cmitmsg | git-commit-tree $tree $PARENTS) &&
-       echo $commit > "$GIT_DIR/HEAD" &&
+       git-update-ref HEAD $commit $current &&
        rm -f -- "$GIT_DIR/MERGE_HEAD"
 else
        echo >&2 "* no commit message?  aborting commit."
index e4a6a68057edf0ff8cd4067f334ddf1eed211e44..27407c1d357d8bf9d621875b1a773cef671ddc3d 100755 (executable)
@@ -54,6 +54,10 @@ append_fetch_head () {
     remote_name_="$3"
     remote_nick_="$4"
     local_name_="$5"
+    case "$6" in
+    t) not_for_merge_='not-for-merge' ;;
+    '') not_for_merge_= ;;
+    esac
 
     # remote-nick is the URL given on the command line (or a shorthand)
     # remote-name is the $GIT_DIR relative refs/ path we computed
@@ -78,10 +82,11 @@ append_fetch_head () {
     if git-cat-file commit "$head_" >/dev/null 2>&1
     then
        headc_=$(git-rev-parse --verify "$head_^0") || exit
-       echo "$headc_   $note_" >>$GIT_DIR/FETCH_HEAD
+       echo "$headc_   $not_for_merge_ $note_" >>$GIT_DIR/FETCH_HEAD
        echo >&2 "* committish: $head_"
        echo >&2 "  $note_"
     else
+       echo "$head_    not-for-merge   $note_" >>$GIT_DIR/FETCH_HEAD
        echo >&2 "* non-commit: $head_"
        echo >&2 "  $note_"
     fi
@@ -105,14 +110,16 @@ fast_forward_local () {
        else
                echo >&2 "* $1: storing $3"
        fi
-       echo "$2" >"$GIT_DIR/$1" ;;
+       git-update-ref "$1" "$2" 
+       ;;
 
     refs/heads/*)
-       # NEEDSWORK: use the same cmpxchg protocol here.
-       echo "$2" >"$GIT_DIR/$1.lock"
-       if test -f "$GIT_DIR/$1"
+       # $1 is the ref being updated.
+       # $2 is the new value for the ref.
+       local=$(git-rev-parse --verify "$1^0" 2>/dev/null)
+       if test "$local"
        then
-           local=$(git-rev-parse --verify "$1^0") &&
+           # Require fast-forward.
            mb=$(git-merge-base "$local" "$2") &&
            case "$2,$mb" in
            $local,*)
@@ -120,34 +127,34 @@ fast_forward_local () {
                ;;
            *,$local)
                echo >&2 "* $1: fast forward to $3"
+               git-update-ref "$1" "$2" "$local"
                ;;
            *)
                false
                ;;
            esac || {
                echo >&2 "* $1: does not fast forward to $3;"
-               case "$force,$single_force" in
-               t,* | *,t)
+               case ",$force,$single_force," in
+               *,t,*)
                        echo >&2 "  forcing update."
+                       git-update-ref "$1" "$2" "$local"
                        ;;
                *)
-                       mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1.remote"
-                       echo >&2 "  leaving it in '$1.remote'"
+                       echo >&2 "  not updating."
                        ;;
                esac
            }
        else
-               echo >&2 "* $1: storing $3"
+           echo >&2 "* $1: storing $3"
+           git-update-ref "$1" "$2"
        fi
-       test -f "$GIT_DIR/$1.lock" &&
-           mv "$GIT_DIR/$1.lock" "$GIT_DIR/$1"
        ;;
     esac
 }
 
 case "$update_head_ok" in
 '')
-       orig_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
+       orig_head=$(git-rev-parse --verify HEAD 2>/dev/null)
        ;;
 esac
 
@@ -157,6 +164,13 @@ do
 
     # These are relative path from $GIT_DIR, typically starting at refs/
     # but may be HEAD
+    if expr "$ref" : '\.' >/dev/null
+    then
+       not_for_merge=t
+       ref=$(expr "$ref" : '\.\(.*\)')
+    else
+       not_for_merge=
+    fi
     if expr "$ref" : '\+' >/dev/null
     then
        single_force=t
@@ -184,7 +198,7 @@ do
     rsync://*)
        TMP_HEAD="$GIT_DIR/TMP_HEAD"
        rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
-       head=$(git-rev-parse TMP_HEAD)
+       head=$(git-rev-parse --verify TMP_HEAD)
        rm -f "$TMP_HEAD"
        test "$rsync_slurped_objects" || {
            rsync -av --ignore-existing --exclude info \
@@ -216,7 +230,8 @@ do
        continue ;;
     esac
 
-    append_fetch_head "$head" "$remote" "$remote_name" "$remote_nick" "$local_name"
+    append_fetch_head "$head" "$remote" \
+       "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
 
 done
 
@@ -241,16 +256,27 @@ http://* | https://* | rsync://* )
            case "$ref" in
            +$remote_name:*)
                single_force=t
+               not_for_merge=
+               found="$ref"
+               break ;;
+           .+$remote_name:*)
+               single_force=t
+               not_for_merge=t
+               found="$ref"
+               break ;;
+           .$remote_name:*)
+               not_for_merge=t
                found="$ref"
                break ;;
            $remote_name:*)
+               not_for_merge=
                found="$ref"
                break ;;
            esac
        done
-
        local_name=$(expr "$found" : '[^:]*:\(.*\)')
-       append_fetch_head "$sha1" "$remote" "$remote_name" "$remote_nick" "$local_name"
+       append_fetch_head "$sha1" "$remote" \
+               "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
     done || exit
     ;;
 esac
@@ -261,10 +287,10 @@ case ",$update_head_ok,$orig_head," in
 *,, | t,* )
        ;;
 *)
-       curr_head=$(cat "$GIT_DIR/HEAD" 2>/dev/null)
+       curr_head=$(git-rev-parse --verify HEAD 2>/dev/null)
        if test "$curr_head" != "$orig_head"
        then
-               echo "$orig_head" >$GIT_DIR/HEAD
+               git-update-ref HEAD "$orig_head"
                die "Cannot fetch into the current branch."
        fi
        ;;
index f0f3100eb1c089efd990b71bb747f4dd0cd035f9..778388e254e8ecc07494c168aec503e3bc511fb3 100755 (executable)
@@ -31,6 +31,8 @@ sub andjoin {
        my ($bname, $tname, $gname, $src);
        chomp;
        s/^[0-9a-f]*    //;
+       next if (/^not-for-merge/);
+       s/^     //;
        if (s/ of (.*)$//) {
                $src = $1;
        } else {
@@ -86,7 +88,7 @@ sub andjoin {
                            $src{$src}{GENERIC});
        my $this = join(', ', @this);
        if ($src ne '.') {
-               $this .= " from $src";
+               $this .= " of $src";
        }
        push @msg, $this;
 }
index 7607e819c355fd30923c520b35ab4de7b918f013..29e86c695320b3d575314bc7c0be9eea0fd1b04a 100755 (executable)
@@ -24,7 +24,9 @@ dropsave() {
 }
 
 savestate() {
-       git diff -r -z --name-only $head | cpio -0 -o >"$GIR_DIR/MERGE_SAVE"
+       # Stash away any local modifications.
+       git-diff-index -r -z --name-only $head |
+       cpio -0 -o >"$GIR_DIR/MERGE_SAVE"
 }
 
 restorestate() {
@@ -114,8 +116,9 @@ case "$#,$common" in
        # Again the most common case of merging one remote.
        echo "Updating from $head to $1."
        git-update-index --refresh 2>/dev/null
-       git-read-tree -u -m $head "$1" || exit 1
-       git-rev-parse --verify "$1^0" > "$GIT_DIR/HEAD"
+       git-read-tree -u -m $head "$1" &&
+       new_head=$(git-rev-parse --verify "$1^0") &&
+       git-update-ref HEAD "$new_head" "$head" || exit 1
        summary "$1"
        dropsave
        exit 0
@@ -149,12 +152,7 @@ esac
 # we use, it would operate on the index, possibly affecting the
 # working tree, and when resolved cleanly, have the desired tree
 # in the index -- this means that the index must be in sync with
-# the $head commit.
-files=$(git-diff-index --cached --name-only $head) || exit
-if [ "$files" ]; then
-   echo >&2 "Dirty index: cannot merge (dirty: $files)"
-   exit 1
-fi
+# the $head commit.  The strategies are responsible to ensure this.
 
 case "$use_strategies" in
 ?*' '?*)
@@ -218,9 +216,9 @@ then
     do
         parents="$parents -p $remote"
     done
-    result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents)
+    result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree $parents) || exit
     echo "Committed merge $result_commit, made by $wt_strategy."
-    echo $result_commit >"$GIT_DIR/HEAD"
+    git-update-ref HEAD $result_commit $head
     summary $result_commit
     dropsave
     exit 0
index abc682025e5316e7d8612e5aa2057a700f618481..d2471af3c8a002c175bf9b1370039b9e7d4ab946 100755 (executable)
@@ -86,5 +86,5 @@ esac
 result_commit=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD" |
                git-commit-tree $MRT $PARENT)
 echo "Committed merge $result_commit"
-echo $result_commit >"$GIT_DIR"/HEAD
+git-update-ref HEAD $result_commit $head
 git-diff-tree -p $head $result_commit | git-apply --stat
index a9db0cd82558af9bebec083450b35348a1d0b29a..4d8a572a9903179494c7cc4f8a72729a47f1c12b 100755 (executable)
@@ -65,8 +65,11 @@ get_remote_default_refs_for_push () {
        esac
 }
 
-# Subroutine to canonicalize remote:local notation
+# Subroutine to canonicalize remote:local notation.
 canon_refs_list_for_fetch () {
+       # Leave only the first one alone; add prefix . to the rest
+       # to prevent the secondary branches to be merged by default.
+       dot_prefix=
        for ref
        do
                force=
@@ -91,7 +94,8 @@ canon_refs_list_for_fetch () {
                heads/* | tags/* ) local="refs/$local" ;;
                *) local="refs/heads/$local" ;;
                esac
-               echo "${force}${remote}:${local}"
+               echo "${dot_prefix}${force}${remote}:${local}"
+               dot_prefix=.
        done
 }
 
@@ -107,6 +111,9 @@ get_remote_default_refs_for_fetch () {
                echo "refs/heads/${remote_branch}:refs/heads/$1"
                ;;
        remotes)
+               # This prefixes the second and later default refspecs
+               # with a '.', to signal git-fetch to mark them
+               # not-for-merge.
                canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
                                                s///p
                                        }' "$GIT_DIR/remotes/$1")
index e3d11961b0a5a7608648348153bde0ab6e7ccfff..1f4a05d09eed7a7ae6be9ce4dcdd92f4e0d75131 100755 (executable)
@@ -6,10 +6,10 @@
 
 . git-sh-setup || die "Not a git archive"
 
-orig_head=$(cat "$GIT_DIR/HEAD") || die "Pulling into a black hole?"
+orig_head=$(git-rev-parse --verify HEAD) || die "Pulling into a black hole?"
 git-fetch --update-head-ok "$@" || exit 1
 
-curr_head=$(cat "$GIT_DIR/HEAD")
+curr_head=$(git-rev-parse --verify HEAD)
 if test "$curr_head" != "$orig_head"
 then
        # The fetch involved updating the current branch.
@@ -24,7 +24,9 @@ then
                die "You need to first update your working tree."
 fi
 
-merge_head=$(sed -e 's/        .*//' "$GIT_DIR"/FETCH_HEAD | tr '\012' ' ')
+merge_head=$(sed -e '/ not-for-merge   /d' \
+       -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
+       tr '\012' ' ')
 
 case "$merge_head" in
 '')
@@ -38,4 +40,4 @@ case "$merge_head" in
 esac
 
 merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD")
-git-resolve "$(cat "$GIT_DIR"/HEAD)" $merge_head "$merge_name"
+git-resolve "$curr_head" $merge_head "$merge_name"
index 49c8f12e51153f5c7ecbdc5a1778c24ba28f428f..fa95009091525eb9ea65bce1e08f293dfd1eddca 100755 (executable)
@@ -33,7 +33,8 @@ test "$different1$different2" = "" ||
 die "Your working tree does not match $ours_symbolic."
 
 git-read-tree -m -u $ours $upstream &&
-git-rev-parse --verify "$upstream^0" >"$GIT_DIR/HEAD" || exit
+new_head=$(git-rev-parse --verify "$upstream^0") &&
+git-update-ref HEAD "$new_head" || exit
 
 tmp=.rebase-tmp$$
 fail=$tmp-fail
@@ -50,7 +51,7 @@ do
                continue ;;
        esac
        echo >&2 "* Applying: $msg"
-       S=`cat "$GIT_DIR/HEAD"` &&
+       S=$(git-rev-parse --verify HEAD) &&
        git-cherry-pick --replay $commit || {
                echo >&2 "* Not applying the patch and continuing."
                echo $commit >>$fail
index dfa9cb8bb17f6f8694d0c639fe8b1663f9ec3c8f..f9995cadf563a7b3b2c1dcdeea3bf862feac2e4b 100755 (executable)
@@ -60,7 +60,7 @@ then
 else
        rm -f "$GIT_DIR/ORIG_HEAD"
 fi
-echo "$rev" >"$GIT_DIR/HEAD"
+git-update-ref HEAD "$rev"
 
 case "$reset_type" in
 --hard )
index 1f559d8cb91bf88e7ddc0abad55db7ad4550aeef..7d8fb54f952e3f85c8c77b8fd9c67afbe76f0316 100755 (executable)
@@ -45,7 +45,7 @@ case "$common" in
 "$head")
        echo "Updating from $head to $merge."
        git-read-tree -u -m $head $merge || exit 1
-       echo $merge > "$GIT_DIR"/HEAD
+       git-update-ref HEAD "$merge" "$head"
        git-diff-tree -p $head $merge | git-apply --stat
        dropheads
        exit 0
@@ -99,6 +99,6 @@ if [ $? -ne 0 ]; then
 fi
 result_commit=$(echo "$merge_msg" | git-commit-tree $result_tree -p $head -p $merge)
 echo "Committed merge $result_commit"
-echo $result_commit > "$GIT_DIR"/HEAD
+git-update-ref HEAD "$result_commit" "$head"
 git-diff-tree -p $head $result_commit | git-apply --stat
 dropheads
index 0caec10468a1a2525713fbb90d9e212da5034def..33f3949252f2dbf0b724b6cfebde236f7d78d728 100644 (file)
@@ -27,7 +27,7 @@ struct alt_base
        struct alt_base *next;
 };
 
-struct alt_base *alt = NULL;
+static struct alt_base *alt = NULL;
 
 static SHA_CTX c;
 static z_stream stream;
@@ -36,6 +36,10 @@ static int local;
 static int zret;
 
 static int curl_ssl_verify;
+static char *ssl_cert;
+static char *ssl_key;
+static char *ssl_capath;
+static char *ssl_cainfo;
 
 struct buffer
 {
@@ -350,7 +354,7 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
        return 0;
 }
 
-int fetch_object(struct alt_base *repo, unsigned char *sha1)
+static int fetch_object(struct alt_base *repo, unsigned char *sha1)
 {
        char *hex = sha1_to_hex(sha1);
        char *filename = sha1_file_name(sha1);
@@ -522,6 +526,21 @@ int main(int argc, char **argv)
        curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
 #endif
 
+       if ((ssl_cert = getenv("GIT_SSL_CERT")) != NULL) {
+               curl_easy_setopt(curl, CURLOPT_SSLCERT, ssl_cert);
+       }
+       if ((ssl_key = getenv("GIT_SSL_KEY")) != NULL) {
+               curl_easy_setopt(curl, CURLOPT_SSLKEY, ssl_key);
+       }
+#if LIBCURL_VERSION_NUM >= 0x070908
+       if ((ssl_capath = getenv("GIT_SSL_CAPATH")) != NULL) {
+               curl_easy_setopt(curl, CURLOPT_CAPATH, ssl_capath);
+       }
+#endif
+       if ((ssl_cainfo = getenv("GIT_SSL_CAINFO")) != NULL) {
+               curl_easy_setopt(curl, CURLOPT_CAINFO, ssl_cainfo);
+       }
+
        alt = xmalloc(sizeof(*alt));
        alt->base = url;
        alt->got_indices = 0;
index c387e9ea08483ef9cc9fb3a61790eaa544c4973b..d0af8c3d52573fea203aab13612a9103cca78dd9 100755 (executable)
@@ -158,49 +158,33 @@ test_expect_success \
 
 We have so far tested only empty index and clean-and-matching-A index
 case which are trivial.  Make sure index requirements are also
-checked.  The table also lists alternative semantics which is not
-currently implemented.
+checked.
 
-"git-diff-tree -m O A B"
+"git-read-tree -m O A B"
 
      O       A       B         result      index requirements
 -------------------------------------------------------------------
   1  missing missing missing   -           must not exist.
  ------------------------------------------------------------------
-  2  missing missing exists    no merge    must not exist.
-                               ------------------------------------
-    (ALT)                      take B*     must match B, if exists.
+  2  missing missing exists    take B*     must match B, if exists.
  ------------------------------------------------------------------
-  3  missing exists  missing   no merge    must match A and be
-                                           up-to-date, if exists.
-                               ------------------------------------
-    (ALT)                      take A*     must match A, if exists.
+  3  missing exists  missing   take A*     must match A, if exists.
  ------------------------------------------------------------------
   4  missing exists  A!=B      no merge    must match A and be
                                            up-to-date, if exists.
  ------------------------------------------------------------------
-  5  missing exists  A==B      no merge    must match A and be
-                                           up-to-date, if exists.
-                               ------------------------------------
-    (ALT)                      take A      must match A, if exists.
+  5  missing exists  A==B      take A      must match A, if exists.
  ------------------------------------------------------------------
-  6  exists  missing missing   no merge    must not exist.
-                               ------------------------------------
-    (ALT)                      remove      must not exist.
+  6  exists  missing missing   remove      must not exist.
  ------------------------------------------------------------------
   7  exists  missing O!=B      no merge    must not exist.
  ------------------------------------------------------------------
-  8  exists  missing O==B      no merge    must not exist.
-                               ------------------------------------
-    (ALT)                      remove      must not exist.
+  8  exists  missing O==B      remove      must not exist.
  ------------------------------------------------------------------
   9  exists  O!=A    missing   no merge    must match A and be
                                            up-to-date, if exists.
  ------------------------------------------------------------------
- 10  exists  O==A    missing   no merge    must match A and be
-                                           up-to-date, if exists.
-                               ------------------------------------
-    (ALT)                      remove      ditto
+ 10  exists  O==A    missing   remove      ditto
  ------------------------------------------------------------------
  11  exists  O!=A    O!=B      no merge    must match A and be
                      A!=B                  up-to-date, if exists.
@@ -210,10 +194,7 @@ currently implemented.
  ------------------------------------------------------------------
  13  exists  O!=A    O==B      take A      must match A, if exists.
  ------------------------------------------------------------------
- 14  exists  O==A    O!=B      take B      must match A and be
-                                           be up-to-date, if exists.
-                               ------------------------------------
-    (ALT)                      take B      if exists, must either (1)
+ 14  exists  O==A    O!=B      take B      if exists, must either (1)
                                            match A and be up-to-date,
                                            or (2) match B.
  ------------------------------------------------------------------
@@ -223,9 +204,9 @@ currently implemented.
      *multi* in one  in another
 -------------------------------------------------------------------
 
-Note: if we want to implement 2ALT and 3ALT we need to be careful.
-The tree A may contain DF (file) when tree B require DF to be a
-directory by having DF/DF (file).
+Note: we need to be careful in case 2 and 3.  The tree A may contain
+DF (file) when tree B require DF to be a directory by having DF/DF
+(file).
 
 END_OF_CASE_TABLE
 
index 01496f6a92f68d25dd160ec7c42004d7e395fe5b..1863b823240790c450e29c1c82041972713d716b 100644 (file)
@@ -6,7 +6,7 @@ static const char git_update_ref_usage[] = "git-update-ref <refname> <value> [<o
 
 #define MAXDEPTH 5
 
-const char *resolve_ref(const char *path, unsigned char *sha1)
+static const char *resolve_ref(const char *path, unsigned char *sha1)
 {
        int depth = MAXDEPTH, len;
        char buffer[256];