Merge fixes up to GIT 1.0.4
authorJunio C Hamano <junkio@cox.net>
Sat, 24 Dec 2005 08:16:56 +0000 (00:16 -0800)
committerJunio C Hamano <junkio@cox.net>
Sat, 24 Dec 2005 08:16:56 +0000 (00:16 -0800)
Documentation/git-clone.txt
Documentation/git-rev-parse.txt
Makefile
connect.c
debian/changelog
git-clone.sh
git-merge-recursive.py
git-whatchanged.sh
pack-redundant.c
rev-parse.c
t/t6022-merge-rename.sh

index 8410a6d..f943f26 100644 (file)
@@ -8,7 +8,7 @@ git-clone - Clones a repository.
 
 SYNOPSIS
 --------
-'git-clone' [-l [-s]] [-q] [-n] [-u <upload-pack>] <repository> [<directory>]
+'git-clone' [-l [-s]] [-q] [-n] [-o <name>] [-u <upload-pack>] <repository> [<directory>]
 
 DESCRIPTION
 -----------
@@ -56,6 +56,13 @@ OPTIONS
 -n::
        No checkout of HEAD is performed after the clone is complete.
 
+-o <name>::
+       Instead of using the branch name 'origin' to keep track
+       of the upstream repository, use <name> instead.  Note
+       that the shorthand name stored in `remotes/origin` is
+       not affected, but the local branch name to pull the
+       remote `master` branch into is.
+
 --upload-pack <upload-pack>::
 -u <upload-pack>::
        When given, and the repository to clone from is handled
index 431b8f6..d638bfc 100644 (file)
@@ -68,10 +68,15 @@ OPTIONS
        Show all refs found in `$GIT_DIR/refs`.
 
 --show-prefix::
-       When the command is invoked from a directory show the
+       When the command is invoked from a subdirectory, show the
        path of the current directory relative to the top-level
        directory.
 
+--show-cdup::
+       When the command is invoked from a subdirectory, show the
+       path of the top-level directory relative to the current
+       directory (typically a sequence of "../", or an empty string).
+
 --since=datestring, --after=datestring::
        Parses the date string, and outputs corresponding
        --max-age= parameter for git-rev-list command.
index 8d03e0b..3395a9e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -55,7 +55,7 @@ all:
 # Define USE_STDEV below if you want git to care about the underlying device
 # change being considered an inode change from the update-cache perspective.
 
-GIT_VERSION = 1.0.4
+GIT_VERSION = 1.0.GIT
 
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
index 93f6f80..6b6d613 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -561,7 +561,8 @@ int git_connect(int fd[2], char *url, const char *prog)
 {
        char command[1024];
        char *host, *path = url;
-       char *colon = NULL;
+       char *end;
+       int c;
        int pipefd[2][2];
        pid_t pid;
        enum protocol protocol = PROTO_LOCAL;
@@ -571,15 +572,30 @@ int git_connect(int fd[2], char *url, const char *prog)
                *host = '\0';
                protocol = get_protocol(url);
                host += 3;
-               path = strchr(host, '/');
-       }
-       else {
+               c = '/';
+       } else {
                host = url;
-               if ((colon = strchr(host, ':'))) {
+               c = ':';
+       }
+
+       if (host[0] == '[') {
+               end = strchr(host + 1, ']');
+               if (end) {
+                       *end = 0;
+                       end++;
+                       host++;
+               } else
+                       end = host;
+       } else
+               end = host;
+
+       path = strchr(end, c);
+       if (c == ':') {
+               if (path) {
                        protocol = PROTO_SSH;
-                       *colon = '\0';
-                       path = colon + 1;
-               }
+                       *path++ = '\0';
+               } else
+                       path = host;
        }
 
        if (!path || !*path)
index 88e5755..d7f7591 100644 (file)
@@ -1,3 +1,15 @@
+git-core (1.0.GIT-0) unstable; urgency=low
+
+  * Post GIT 1.0 development track.
+
+ -- Junio C Hamano <junkio@cox.net>  Wed, 21 Dec 2005 22:28:33 -0800
+
+git-core (1.0.0.GIT-0) unstable; urgency=low
+
+  * Post GIT 1.0.0 development track.
+
+ -- Junio C Hamano <junkio@cox.net>  Wed, 21 Dec 2005 12:12:05 -0800
+
 git-core (1.0.4-0) unstable; urgency=low
 
   * GIT 1.0.4.
index 280cc2e..377d59e 100755 (executable)
@@ -9,7 +9,7 @@
 unset CDPATH
 
 usage() {
-       echo >&2 "Usage: $0 [-l [-s]] [-q] [-u <upload-pack>] [-n] <repo> [<dir>]"
+       echo >&2 "Usage: $0 [-l [-s]] [-q] [-u <upload-pack>] [-o <name>] [-n] <repo> [<dir>]"
        exit 1
 }
 
@@ -31,25 +31,11 @@ clone_dumb_http () {
        cd "$2" &&
        clone_tmp='.git/clone-tmp' &&
        mkdir -p "$clone_tmp" || exit 1
-       http_fetch "$1/info/refs" "$clone_tmp/refs" &&
-       http_fetch "$1/objects/info/packs" "$clone_tmp/packs" || {
+       http_fetch "$1/info/refs" "$clone_tmp/refs" || {
                echo >&2 "Cannot get remote repository information.
 Perhaps git-update-server-info needs to be run there?"
                exit 1;
        }
-       while read type name
-       do
-               case "$type" in
-               P) ;;
-               *) continue ;;
-               esac &&
-
-               idx=`expr "$name" : '\(.*\)\.pack'`.idx
-               http_fetch "$1/objects/pack/$name" ".git/objects/pack/$name" &&
-               http_fetch "$1/objects/pack/$idx" ".git/objects/pack/$idx" &&
-               git-verify-pack ".git/objects/pack/$idx" || exit 1
-       done <"$clone_tmp/packs"
-
        while read sha1 refname
        do
                name=`expr "$refname" : 'refs/\(.*\)'` &&
@@ -67,6 +53,7 @@ use_local=no
 local_shared=no
 no_checkout=
 upload_pack=
+origin=origin
 while
        case "$#,$1" in
        0,*) break ;;
@@ -75,6 +62,14 @@ while
         *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared) 
           local_shared=yes; use_local=yes ;;
        *,-q|*,--quiet) quiet=-q ;;
+       1,-o) usage;;
+       *,-o)
+               git-check-ref-format "$2" || {
+                   echo >&2 "'$2' is not suitable for a branch name"
+                   exit 1
+               }
+               origin="$2"; shift
+               ;;
        1,-u|1,--upload-pack) usage ;;
        *,-u|*,--upload-pack)
                shift
@@ -208,14 +203,14 @@ then
                mkdir -p .git/remotes &&
                echo >.git/remotes/origin \
                "URL: $repo
-Pull: $head_points_at:origin" &&
-               cp ".git/refs/heads/$head_points_at" .git/refs/heads/origin &&
+Pull: $head_points_at:$origin" &&
+               git-update-ref "refs/heads/$origin" $(git-rev-parse HEAD) &&
                find .git/refs/heads -type f -print |
                while read ref
                do
                        head=`expr "$ref" : '.git/refs/heads/\(.*\)'` &&
                        test "$head_points_at" = "$head" ||
-                       test "origin" = "$head" ||
+                       test "$origin" = "$head" ||
                        echo "Pull: ${head}:${head}"
                done >>.git/remotes/origin
        esac
index f1320a6..56c3641 100755 (executable)
@@ -283,12 +283,20 @@ def updateFileExt(sha, mode, path, updateCache, updateWd):
 def setIndexStages(path,
                    oSHA1, oMode,
                    aSHA1, aMode,
-                   bSHA1, bMode):
+                   bSHA1, bMode,
+                   clear=True):
+    istring = []
+    if clear:
+        istring.append("0 " + ("0" * 40) + "\t" + path + "\0")
+    if oMode:
+        istring.append("%o %s %d\t%s\0" % (oMode, oSHA1, 1, path))
+    if aMode:
+        istring.append("%o %s %d\t%s\0" % (aMode, aSHA1, 2, path))
+    if bMode:
+        istring.append("%o %s %d\t%s\0" % (bMode, bSHA1, 3, path))
+
     runProgram(['git-update-index', '-z', '--index-info'],
-               input="0 " + ("0" * 40) + "\t" + path + "\0" + \
-               "%o %s %d\t%s\0" % (oMode, oSHA1, 1, path) + \
-               "%o %s %d\t%s\0" % (aMode, aSHA1, 2, path) + \
-               "%o %s %d\t%s\0" % (bMode, bSHA1, 3, path))
+               input="".join(istring))
 
 def removeFile(clean, path):
     updateCache = cacheOnly or clean
@@ -570,7 +578,7 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB):
             continue
 
         ren1.processed = True
-        removeFile(True, ren1.srcName)
+
         if ren2:
             # Renamed in 1 and renamed in 2
             assert(ren1.srcName == ren2.srcName)
@@ -598,13 +606,19 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB):
                            'adding as', dstName2, 'instead.')
                     removeFile(False, ren2.dstName)
                 else:
-                    dstName2 = ren1.dstName
+                    dstName2 = ren2.dstName
+                setIndexStages(dstName1,
+                               None, None,
+                               ren1.dstSha, ren1.dstMode,
+                              None, None)
+                setIndexStages(dstName2,
+                               None, None,
+                               None, None,
+                               ren2.dstSha, ren2.dstMode)
 
-                # NEEDSWORK: place dstNameA at stage 2 and dstNameB at stage 3
-                # What about other stages???
-                updateFile(False, ren1.dstSha, ren1.dstMode, dstName1)
-                updateFile(False, ren2.dstSha, ren2.dstMode, dstName2)
             else:
+                removeFile(True, ren1.srcName)
+
                 [resSha, resMode, clean, merge] = \
                          mergeFile(ren1.srcName, ren1.srcSha, ren1.srcMode,
                                    ren1.dstName, ren1.dstSha, ren1.dstMode,
@@ -630,6 +644,8 @@ def processRenames(renamesA, renamesB, branchNameA, branchNameB):
 
                 updateFile(clean, resSha, resMode, ren1.dstName)
         else:
+            removeFile(True, ren1.srcName)
+
             # Renamed in 1, maybe changed in 2
             if renamesA == renames1:
                 stage = 3
index b170f74..80e2500 100755 (executable)
@@ -4,9 +4,15 @@ USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-d
 SUBDIRECTORY_OK='Yes'
 . git-sh-setup
 
+diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@")
+test -z "$diff_tree_flags" &&
+       diff_tree_flags=$(git-repo-config --get whatchanged.difftree)
+test -z "$diff_tree_flags" &&
+       diff_tree_flags='-M --abbrev'
+
 rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
-diff_tree_args=$(git-rev-parse --sq --no-revs "$@") &&
+diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
 
 eval "git-rev-list $rev_list_args" |
-eval "git-diff-tree --stdin --pretty -r $diff_tree_args" |
+eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
 LESS="$LESS -S" ${PAGER:-less}
index 0a43278..1869b38 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "cache.h"
 
+#define BLKSIZE 512
+
 static const char pack_redundant_usage[] =
 "git-pack-redundant [ --verbose ] [ --alt-odb ] < --all | <.pack filename> ...>";
 
@@ -33,29 +35,32 @@ static struct pack_list {
 struct pll {
        struct pll *next;
        struct pack_list *pl;
-       size_t pl_size;
 };
 
 static struct llist_item *free_nodes = NULL;
 
+static inline void llist_item_put(struct llist_item *item)
+{
+       item->next = free_nodes;
+       free_nodes = item;
+}
+
 static inline struct llist_item *llist_item_get()
 {
        struct llist_item *new;
        if ( free_nodes ) {
                new = free_nodes;
                free_nodes = free_nodes->next;
-       } else
-               new = xmalloc(sizeof(struct llist_item));
-
+       } else {
+               int i = 1;
+               new = xmalloc(sizeof(struct llist_item) * BLKSIZE);
+               for(;i < BLKSIZE; i++) {
+                       llist_item_put(&new[i]);
+               }
+       }
        return new;
 }
 
-static inline void llist_item_put(struct llist_item *item)
-{
-       item->next = free_nodes;
-       free_nodes = item;
-}
-
 static void llist_free(struct llist *list)
 {
        while((list->back = list->front)) {
@@ -270,77 +275,58 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
        }
 }
 
-static void pll_insert(struct pll **pll, struct pll **hint_table)
+void pll_free(struct pll *l)
 {
-       struct pll *prev;
-       int i = (*pll)->pl_size - 1;
-
-       if (hint_table[i] == NULL) {
-               hint_table[i--] = *pll;
-               for (; i >= 0; --i) {
-                       if (hint_table[i] != NULL)
-                               break;
+       struct pll *old;
+       struct pack_list *opl;
+
+       while (l) {
+               old = l;
+               while (l->pl) {
+                       opl = l->pl;
+                       l->pl = opl->next;
+                       free(opl);
                }
-               if (hint_table[i] == NULL) /* no elements in list */
-                       die("Why did this happen?");
+               l = l->next;
+               free(old);
        }
-
-       prev = hint_table[i];
-       while (prev->next && prev->next->pl_size < (*pll)->pl_size)
-               prev = prev->next;
-
-       (*pll)->next = prev->next;
-       prev->next = *pll;
 }
 
 /* all the permutations have to be free()d at the same time,
  * since they refer to each other
  */
-static struct pll * get_all_permutations(struct pack_list *list)
+static struct pll * get_permutations(struct pack_list *list, int n)
 {
-       struct pll *subset, *pll, *new_pll = NULL; /*silence warning*/
-       static struct pll **hint = NULL;
-       if (hint == NULL)
-               hint = xcalloc(pack_list_size(list), sizeof(struct pll *));
-               
-       if (list == NULL)
+       struct pll *subset, *ret = NULL, *new_pll = NULL, *pll;
+
+       if (list == NULL || pack_list_size(list) < n || n == 0)
                return NULL;
 
-       if (list->next == NULL) {
-               new_pll = xmalloc(sizeof(struct pll));
-               hint[0] = new_pll;
-               new_pll->next = NULL;
-               new_pll->pl = list;
-               new_pll->pl_size = 1;
-               return new_pll;
+       if (n == 1) {
+               while (list) {
+                       new_pll = xmalloc(sizeof(pll));
+                       new_pll->pl = NULL;
+                       pack_list_insert(&new_pll->pl, list);
+                       new_pll->next = ret;
+                       ret = new_pll;
+                       list = list->next;
+               }
+               return ret;
        }
 
-       pll = subset = get_all_permutations(list->next);
-       while (pll) {
-               if (pll->pl->pack == list->pack) {
-                       pll = pll->next;
-                       continue;
+       while (list->next) {
+               subset = get_permutations(list->next, n - 1);
+               while (subset) {
+                       new_pll = xmalloc(sizeof(pll));
+                       new_pll->pl = subset->pl;
+                       pack_list_insert(&new_pll->pl, list);
+                       new_pll->next = ret;
+                       ret = new_pll;
+                       subset = subset->next;
                }
-               new_pll = xmalloc(sizeof(struct pll));
-
-               new_pll->pl = xmalloc(sizeof(struct pack_list));
-               memcpy(new_pll->pl, list, sizeof(struct pack_list));
-               new_pll->pl->next = pll->pl;
-               new_pll->pl_size = pll->pl_size + 1;
-               
-               pll_insert(&new_pll, hint);
-
-               pll = pll->next;
-       }
-       /* add ourself */
-       new_pll = xmalloc(sizeof(struct pll));
-       new_pll->pl = xmalloc(sizeof(struct pack_list));
-       memcpy(new_pll->pl, list, sizeof(struct pack_list));
-       new_pll->pl->next = NULL;
-       new_pll->pl_size = 1;
-       pll_insert(&new_pll, hint);
-
-       return hint[0];
+               list = list->next;
+       }
+       return ret;
 }
 
 static int is_superset(struct pack_list *pl, struct llist *list)
@@ -428,6 +414,7 @@ static void minimize(struct pack_list **min)
        struct pll *perm, *perm_all, *perm_ok = NULL, *new_perm;
        struct llist *missing;
        size_t min_perm_size = (size_t)-1, perm_size;
+       int n;
 
        pl = local_packs;
        while (pl) {
@@ -441,8 +428,7 @@ static void minimize(struct pack_list **min)
        missing = llist_copy(all_objects);
        pl = unique;
        while (pl) {
-               llist_sorted_difference_inplace(missing,
-                                               pl->all_objects);
+               llist_sorted_difference_inplace(missing, pl->all_objects);
                pl = pl->next;
        }
 
@@ -453,19 +439,21 @@ static void minimize(struct pack_list **min)
        }
 
        /* find the permutations which contain all missing objects */
-       perm_all = perm = get_all_permutations(non_unique);
-       while (perm) {
-               if (perm_ok && perm->pl_size > perm_ok->pl_size)
-                       break; /* ignore all larger permutations */
-               if (is_superset(perm->pl, missing)) {
-                       new_perm = xmalloc(sizeof(struct pll));
-                       memcpy(new_perm, perm, sizeof(struct pll));
-                       new_perm->next = perm_ok;
-                       perm_ok = new_perm;
+       for (n = 1; n <= pack_list_size(non_unique) && !perm_ok; n++) {
+               perm_all = perm = get_permutations(non_unique, n);
+               while (perm) {
+                       if (is_superset(perm->pl, missing)) {
+                               new_perm = xmalloc(sizeof(struct pll));
+                               memcpy(new_perm, perm, sizeof(struct pll));
+                               new_perm->next = perm_ok;
+                               perm_ok = new_perm;
+                       }
+                       perm = perm->next;
                }
-               perm = perm->next;
+               if (perm_ok)
+                       break;
+               pll_free(perm_all);
        }
-       
        if (perm_ok == NULL)
                die("Internal error: No complete sets found!\n");
 
@@ -537,6 +525,7 @@ static void scan_alt_odb_packs(void)
                                                        alt->all_objects);
                        local = local->next;
                }
+               llist_sorted_difference_inplace(all_objects, alt->all_objects);
                alt = alt->next;
        }
 }
index bb4949a..0c951af 100644 (file)
@@ -216,6 +216,18 @@ int main(int argc, char **argv)
                                        puts(prefix);
                                continue;
                        }
+                       if (!strcmp(arg, "--show-cdup")) {
+                               const char *pfx = prefix;
+                               while (pfx) {
+                                       pfx = strchr(pfx, '/');
+                                       if (pfx) {
+                                               pfx++;
+                                               printf("../");
+                                       }
+                               }
+                               putchar('\n');
+                               continue;
+                       }
                        if (!strcmp(arg, "--git-dir")) {
                                const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                                static char cwd[PATH_MAX];
index 153b9e4..1292caf 100755 (executable)
@@ -161,4 +161,41 @@ test_expect_success 'pull unrenaming branch into renaming one' \
        }
 '
 
+test_expect_success 'pull conflicting renames' \
+'
+       git reset --hard
+       git show-branch
+       git pull . blue && {
+               echo "BAD: should have conflicted"
+               exit 1
+       }
+       test "$(git ls-files -u A | wc -l)" -eq 1 || {
+               echo "BAD: should have left a stage"
+               exit 1  
+       }
+       test "$(git ls-files -u B | wc -l)" -eq 1 || {
+               echo "BAD: should have left a stage"
+               exit 1  
+       }
+       test "$(git ls-files -u C | wc -l)" -eq 1 || {
+               echo "BAD: should have left a stage"
+               exit 1  
+       }
+       test "$(git ls-files -s N | wc -l)" -eq 1 || {
+               echo "BAD: should have merged N"
+               exit 1  
+       }
+       sed -ne "/^g/{
+       p
+       q
+       }" B | grep red || {
+               echo "BAD: should have listed our change first"
+               exit 1
+       }
+       test "$(git diff white N | wc -l)" -eq 0 || {
+               echo "BAD: should have taken colored branch"
+               exit 1
+       }
+'
+
 test_done