From 1f7d1a53fed40608e76200f941e6689b53752747 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 4 Feb 2007 03:25:12 -0800 Subject: [PATCH 1/5] git-clone --reference: saner handling of borrowed symrefs. When using --reference to borrow objects from a neighbouring repository while cloning, we copy the entire set of refs under temporary "refs/reference-tmp/refs" space and set up the object alternates. However, a textual symref copied this way would not point at the right place, and causes later steps to emit error messages (which is harmless but still alarming). This is most visible when using a clone created with the separate-remote layout as a reference, because such a repository would have refs/remotes/origin/HEAD with 'ref: refs/remotes/origin/master' as its contents. Although we do not create symbolic-link based refs anymore, they have the same problem because they are always supposed to be relative to refs/ hierarchy (we dereference by hand, so it only is good for HEAD and nothing else). In either case, the solution is simply to remove them after copying under refs/reference-tmp; if a symref points at a true ref, that true ref itself is enough to ensure that objects reachable from it do not needlessly get fetched. Signed-off-by: Junio C Hamano --- git-clone.sh | 29 ++++++++++++++++++++++++++- t/t5700-clone-reference.sh | 40 +++++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/git-clone.sh b/git-clone.sh index 4ddfa774ec..171099674d 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -190,7 +190,34 @@ then (cd "$GIT_DIR/refs" && mkdir reference-tmp && cd reference-tmp && - tar xf -) + tar xf - && + find refs ! -type d -print | + while read ref + do + if test -h "$ref" + then + # Old-style symbolic link ref. Not likely + # to appear under refs/ but we might as well + # deal with them. + : + elif test -f "$ref" + then + point=$(cat "$ref") && + case "$point" in + 'ref: '*) ;; + *) continue ;; + esac + fi + # The above makes true ref to 'continue' and + # we will come here when we are looking at + # symbolic link ref or a textual symref (or + # garbage, like fifo). + # The true ref pointed at by it is enough to + # ensure that we do not fetch objects reachable + # from it. + rm -f "$ref" + done + ) else die "reference repository '$reference' is not a local directory." fi diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh index dd9caad1c2..6d43252593 100755 --- a/t/t5700-clone-reference.sh +++ b/t/t5700-clone-reference.sh @@ -26,7 +26,7 @@ git prune' cd "$base_dir" -test_expect_success 'cloning with reference' \ +test_expect_success 'cloning with reference (-l -s)' \ 'git clone -l -s --reference B A C' cd "$base_dir" @@ -50,6 +50,28 @@ diff expected current' cd "$base_dir" +test_expect_success 'cloning with reference (no -l -s)' \ +'git clone --reference B A D' + +cd "$base_dir" + +test_expect_success 'existence of info/alternates' \ +'test `wc -l expected && +git count-objects > current && +diff expected current' + +cd "$base_dir" + test_expect_success 'updating origin' \ 'cd A && echo third > file3 && @@ -75,4 +97,20 @@ diff expected current' cd "$base_dir" +test_expect_success 'pulling changes from origin' \ +'cd D && +git pull origin' + +cd "$base_dir" + +# the 5 local objects are expected; file3 blob, commit in A to add it +# and its tree, and 2 are our tree and the merge commit. +test_expect_success 'check objects expected to exist locally' \ +'cd D && +echo "5 objects" > expected && +git count-objects | cut -d, -f1 > current && +diff expected current' + +cd "$base_dir" + test_done From 6e2e1cfb81a6a6de9fc074bd26bed8a45f73251f Mon Sep 17 00:00:00 2001 From: Robin Rosenberg Date: Sun, 4 Feb 2007 17:16:39 +0100 Subject: [PATCH 2/5] Why is it bad to rewind a branch that has already been pushed out? Mention git-revert as an alternative to git-reset to revert changes. Signed-off-by: Robin Rosenberg Signed-off-by: Junio C Hamano --- Documentation/tutorial.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt index 5fc5be5a28..129c5c5f5b 100644 --- a/Documentation/tutorial.txt +++ b/Documentation/tutorial.txt @@ -461,6 +461,8 @@ this branch. If this branch is the only branch containing those commits, they will be lost. Also, don't use "git reset" on a publicly-visible branch that other developers pull from, as it will force needless merges on other developers to clean up the history. +If you need to undo changes that you have pushed, use gitlink:git-revert[1] +instead. The git grep command can search for strings in any version of your project, so From 756373da254dbe8bd03bd83ec658d3f015fee958 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 3 Feb 2007 16:23:38 -0800 Subject: [PATCH 3/5] Revert "Allow branch.*.merge to talk about remote tracking branches." This reverts commit 80c797764a6b6a373f0f1f47d7f56b0d950418a9. Back when I committed this, it seemed to be a good idea. People who always use remote tracking branches can optionally use the local name they happen to use to specify what to merge, which meant that I did not have to teach them why we use the name at the remote side every time they are confused. But allowing it seems to break other people's scripts. The real solution is not to allow more ways to express the same thing, but to educate people to use the right syntax. Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 3e783b7b05..5208ee6ce0 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -174,12 +174,8 @@ canon_refs_list_for_fetch () { else for merge_branch in $merge_branches do - if test "$remote" = "$merge_branch" || - test "$local" = "$merge_branch" - then - dot_prefix= - break - fi + [ "$remote" = "$merge_branch" ] && + dot_prefix= && break done fi case "$remote" in From 11dbe9e88016f3894eda79c7437f6c3bf79e155e Mon Sep 17 00:00:00 2001 From: Gerrit Pape Date: Sat, 3 Feb 2007 22:38:59 +0000 Subject: [PATCH 4/5] git-archimport: initial import needs empty directory git-archimport should better refuse to start an initial import if the current directory is not empty. (http://bugs.debian.org/400508) Signed-off-by: Gerrit Pape Signed-off-by: Junio C Hamano --- git-archimport.perl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/git-archimport.perl b/git-archimport.perl index 2e15781246..66aaeae102 100755 --- a/git-archimport.perl +++ b/git-archimport.perl @@ -95,6 +95,15 @@ $ENV{'TMPDIR'} = $opt_t if $opt_t; # $ENV{TMPDIR} will affect tempdir() calls: my $tmp = tempdir('git-archimport-XXXXXX', TMPDIR => 1, CLEANUP => 1); $opt_v && print "+ Using $tmp as temporary directory\n"; +unless (-d $git_dir) { # initial import needs empty directory + opendir DIR, '.' or die "Unable to open current directory: $!\n"; + while (my $entry = readdir DIR) { + $entry =~ /^\.\.?$/ or + die "Initial import needs an empty current working directory.\n" + } + closedir DIR +} + my %reachable = (); # Arch repositories we can access my %unreachable = (); # Arch repositories we can't access :< my @psets = (); # the collection From 798123af21e1660cb606ab730ce721f354957719 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 4 Feb 2007 17:50:14 -0800 Subject: [PATCH 5/5] Rename get_ident() to fmt_ident() and make it available to outside This makes the functionality of ident.c::get_ident() available to other callers. Signed-off-by: Junio C Hamano --- cache.h | 1 + ident.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cache.h b/cache.h index 201704bacf..38a9bc02f6 100644 --- a/cache.h +++ b/cache.h @@ -321,6 +321,7 @@ unsigned long approxidate(const char *); extern const char *git_author_info(int); extern const char *git_committer_info(int); +extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); struct checkout { const char *base_dir; diff --git a/ident.c b/ident.c index a6fc7b5e11..bb03bddd34 100644 --- a/ident.c +++ b/ident.c @@ -185,8 +185,8 @@ static const char *env_hint = "Add --global to set your account\'s default\n" "\n"; -static const char *get_ident(const char *name, const char *email, - const char *date_str, int error_on_no_name) +const char *fmt_ident(const char *name, const char *email, + const char *date_str, int error_on_no_name) { static char buffer[1000]; char date[50]; @@ -233,7 +233,7 @@ static const char *get_ident(const char *name, const char *email, const char *git_author_info(int error_on_no_name) { - return get_ident(getenv("GIT_AUTHOR_NAME"), + return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"), error_on_no_name); @@ -241,7 +241,7 @@ const char *git_author_info(int error_on_no_name) const char *git_committer_info(int error_on_no_name) { - return get_ident(getenv("GIT_COMMITTER_NAME"), + return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"), error_on_no_name);