From 668f3aa776bcd293de08413bf1b25b91c15f1b01 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:27 -0600 Subject: [PATCH 01/41] fast-export: Set revs.topo_order before calling setup_revisions setup_revisions sets a variety of flags based on the setting of other flags, such as setting the limited flag when topo_order is set. To avoid circumventing any invariants created by setup_revisions, we set revs.topo_order before calling it rather than after. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- builtin-fast-export.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 6cef810312..e0cfa606dc 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -514,6 +514,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); init_revisions(&revs, prefix); + revs.topo_order = 1; argc = setup_revisions(argc, argv, &revs, NULL); argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0); if (argc > 1) @@ -524,7 +525,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) get_tags_and_duplicates(&revs.pending, &extra_refs); - revs.topo_order = 1; if (prepare_revision_walk(&revs)) die("revision walk setup failed"); revs.diffopt.format_callback = show_filemodify; From 02c48cd69b3ebfac3867f0f9ceb1503a5af118fc Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:28 -0600 Subject: [PATCH 02/41] fast-export: Omit tags that tag trees Commit c0582c53bcf4e83bba70e1ad23abbad31f96ebc8 introduced logic to just omit tags that point to tree objects. However, these objects were still being output and were pointing at "mark :0", which caused fast-import to crash. This patch makes sure such tags (including deeper nestings such as tags of tags of trees), are omitted. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- builtin-fast-export.c | 15 +++++++++++++++ t/t9301-fast-export.sh | 8 +++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index e0cfa606dc..8c90a2df67 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -289,6 +289,21 @@ static void handle_tag(const char *name, struct tag *tag) char *buf; const char *tagger, *tagger_end, *message; size_t message_size = 0; + struct object *tagged; + + /* Trees have no identifer in fast-export output, thus we have no way + * to output tags of trees, tags of tags of trees, etc. Simply omit + * such tags. + */ + tagged = tag->tagged; + while (tagged->type == OBJ_TAG) { + tagged = ((struct tag *)tagged)->tagged; + } + if (tagged->type == OBJ_TREE) { + warning("Omitting tag %s,\nsince tags of trees (or tags of tags of trees, etc.) are not supported.", + sha1_to_hex(tag->object.sha1)); + return; + } buf = read_sha1_file(tag->object.sha1, &type, &size); if (!buf) diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index 8c8a9e63c2..3f13e6b15c 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -271,8 +271,14 @@ test_expect_success 'set-up a few more tags for tag export tests' ' git tag -a tag-obj_tag-obj -m "tagging a tag" tree_tag-obj ' +test_expect_success 'tree_tag' ' + mkdir result && + (cd result && git init) && + git fast-export tree_tag > fe-stream && + (cd result && git fast-import < ../fe-stream) +' + # NEEDSWORK: not just check return status, but validate the output -test_expect_success 'tree_tag' 'git fast-export tree_tag' test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj' test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag' test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj' From 2374502c6ca1c8007cb35682f13fb5db044df9ea Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:29 -0600 Subject: [PATCH 03/41] fast-export: Make sure we show actual ref names instead of "(null)" The code expects a ref name to be provided in commit->util. While there was some code to set commit->util, it only worked in cases where there was an unbroken chain of revisions from a ref to the relevant commit. In cases such as running git fast-export --parents master -- COPYING commit->util would fail to be set. The old method of setting commit->util has been removed in favor of requesting show_source from the revision traversal machinery (related to the "--source" option of "git log" family of commands.) However, this change does not fix cases like git fast export master~1 or git fast export :/arguments since in such cases commit->util will be "master~1" or ":/arguments" while we need the actual ref (e.g. "refs/heads/master") Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- builtin-fast-export.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 8c90a2df67..43a7e17d3e 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -530,6 +530,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) init_revisions(&revs, prefix); revs.topo_order = 1; + revs.show_source = 1; argc = setup_revisions(argc, argv, &revs, NULL); argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0); if (argc > 1) @@ -546,11 +547,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) DIFF_OPT_SET(&revs.diffopt, RECURSIVE); while ((commit = get_revision(&revs))) { if (has_unshown_parent(commit)) { - struct commit_list *parent = commit->parents; add_object_array(&commit->object, NULL, &commits); - for (; parent; parent = parent->next) - if (!parent->item->util) - parent->item->util = commit->util; } else { handle_commit(commit, &revs); From 32164131db0984544b222ac515f95f917fa01441 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:30 -0600 Subject: [PATCH 04/41] fast-export: Do parent rewriting to avoid dropping relevant commits When specifying paths to export, parent rewriting must be turned on for fast-export to output anything at all. Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- builtin-fast-export.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 43a7e17d3e..9b8bd37290 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -531,6 +531,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) init_revisions(&revs, prefix); revs.topo_order = 1; revs.show_source = 1; + revs.rewrite_parents = 1; argc = setup_revisions(argc, argv, &revs, NULL); argc = parse_options(argc, argv, prefix, options, fast_export_usage, 0); if (argc > 1) From 2d8ad46919213ebbd7bb72eb5b56cca8cc3ae07f Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:31 -0600 Subject: [PATCH 05/41] fast-export: Add a --tag-of-filtered-object option for newly dangling tags When providing a list of paths to limit what is exported, the object that a tag points to can be filtered out entirely. This new switch allows the user to specify what should happen to the tag in such a case. The default action, 'abort' will exit with an error message. With 'drop', the tag will simply be omitted from the output. With 'rewrite', if the object tagged was a commit, the tag will be modified to tag an alternate commit. The alternate commit is determined by treating the original commit as the "parent" of the tag and then using the parent rewriting algorithm of the revision traversal machinery (related to the "--parents" option of "git rev-list") Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- Documentation/git-fast-export.txt | 11 ++++++ builtin-fast-export.c | 59 +++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 0c9eb567cb..194abdeeba 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -36,6 +36,17 @@ when encountering a signed tag. With 'strip', the tags will be made unsigned, with 'verbatim', they will be silently exported and with 'warn', they will be exported, but you will see a warning. +--tag-of-filtered-object=(abort|drop|rewrite):: + Specify how to handle tags whose tagged objectis filtered out. + Since revisions and files to export can be limited by path, + tagged objects may be filtered completely. ++ +When asking to 'abort' (which is the default), this program will die +when encountering such a tag. With 'drop' it will omit such tags from +the output. With 'rewrite', if the tagged object is a commit, it will +rewrite the tag to tag an ancestor commit (via parent rewriting; see +linkgit:git-rev-list[1]) + -M:: -C:: Perform move and/or copy detection, as described in the diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 9b8bd37290..dc2c6ab173 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -23,7 +23,8 @@ static const char *fast_export_usage[] = { }; static int progress; -static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT; +static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT; +static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT; static int fake_missing_tagger; static int parse_opt_signed_tag_mode(const struct option *opt, @@ -42,6 +43,20 @@ static int parse_opt_signed_tag_mode(const struct option *opt, return 0; } +static int parse_opt_tag_of_filtered_mode(const struct option *opt, + const char *arg, int unset) +{ + if (unset || !strcmp(arg, "abort")) + tag_of_filtered_mode = ABORT; + else if (!strcmp(arg, "drop")) + tag_of_filtered_mode = DROP; + else if (!strcmp(arg, "rewrite")) + tag_of_filtered_mode = REWRITE; + else + return error("Unknown tag-of-filtered mode: %s", arg); + return 0; +} + static struct decoration idnums; static uint32_t last_idnum; @@ -290,6 +305,8 @@ static void handle_tag(const char *name, struct tag *tag) const char *tagger, *tagger_end, *message; size_t message_size = 0; struct object *tagged; + int tagged_mark; + struct commit *p; /* Trees have no identifer in fast-export output, thus we have no way * to output tags of trees, tags of tags of trees, etc. Simply omit @@ -348,10 +365,45 @@ static void handle_tag(const char *name, struct tag *tag) } } + /* handle tag->tagged having been filtered out due to paths specified */ + tagged = tag->tagged; + tagged_mark = get_object_mark(tagged); + if (!tagged_mark) { + switch(tag_of_filtered_mode) { + case ABORT: + die ("Tag %s tags unexported object; use " + "--tag-of-filtered-object= to handle it.", + sha1_to_hex(tag->object.sha1)); + case DROP: + /* Ignore this tag altogether */ + return; + case REWRITE: + if (tagged->type != OBJ_COMMIT) { + die ("Tag %s tags unexported %s!", + sha1_to_hex(tag->object.sha1), + typename(tagged->type)); + } + p = (struct commit *)tagged; + for (;;) { + if (p->parents && p->parents->next) + break; + if (p->object.flags & UNINTERESTING) + break; + if (!(p->object.flags & TREESAME)) + break; + if (!p->parents) + die ("Can't find replacement commit for tag %s\n", + sha1_to_hex(tag->object.sha1)); + p = p->parents->item; + } + tagged_mark = get_object_mark(&p->object); + } + } + if (!prefixcmp(name, "refs/tags/")) name += 10; printf("tag %s\nfrom :%d\n%.*s%sdata %d\n%.*s\n", - name, get_object_mark(tag->tagged), + name, tagged_mark, (int)(tagger_end - tagger), tagger, tagger == tagger_end ? "" : "\n", (int)message_size, (int)message_size, message ? message : ""); @@ -513,6 +565,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) OPT_CALLBACK(0, "signed-tags", &signed_tag_mode, "mode", "select handling of signed tags", parse_opt_signed_tag_mode), + OPT_CALLBACK(0, "tag-of-filtered-object", &tag_of_filtered_mode, "mode", + "select handling of tags that tag filtered objects", + parse_opt_tag_of_filtered_mode), OPT_STRING(0, "export-marks", &export_filename, "FILE", "Dump marks to this file"), OPT_STRING(0, "import-marks", &import_filename, "FILE", From 25e0ca5dd61f8a4625393fa1b71e1f88c9fab754 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:32 -0600 Subject: [PATCH 06/41] Add new fast-export testcases The testcases test the new --tag-of-filtered-object option, the output when limiting what to export by path, and test behavior when no exact-ref revision is included (e.g. master~8 present on command line but not master). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- t/t9301-fast-export.sh | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index 3f13e6b15c..356964e53a 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -262,6 +262,94 @@ test_expect_success 'cope with tagger-less tags' ' ' +test_expect_success 'setup for limiting exports by PATH' ' + mkdir limit-by-paths && + cd limit-by-paths && + git init && + echo hi > there && + git add there && + git commit -m "First file" && + echo foo > bar && + git add bar && + git commit -m "Second file" && + git tag -a -m msg mytag && + echo morefoo >> bar && + git add bar && + git commit -m "Change to second file" && + cd .. +' + +cat > limit-by-paths/expected << EOF +blob +mark :1 +data 3 +hi + +reset refs/tags/mytag +commit refs/tags/mytag +mark :2 +author A U Thor 1112912713 -0700 +committer C O Mitter 1112912713 -0700 +data 11 +First file +M 100644 :1 there + +EOF + +test_expect_success 'dropping tag of filtered out object' ' + cd limit-by-paths && + git fast-export --tag-of-filtered-object=drop mytag -- there > output && + test_cmp output expected && + cd .. +' + +cat >> limit-by-paths/expected << EOF +tag mytag +from :2 +tagger C O Mitter 1112912713 -0700 +data 4 +msg + +EOF + +test_expect_success 'rewriting tag of filtered out object' ' + cd limit-by-paths && + git fast-export --tag-of-filtered-object=rewrite mytag -- there > output && + test_cmp output expected && + cd .. +' + +cat > limit-by-paths/expected << EOF +blob +mark :1 +data 4 +foo + +blob +mark :2 +data 3 +hi + +reset refs/heads/master +commit refs/heads/master +mark :3 +author A U Thor 1112912713 -0700 +committer C O Mitter 1112912713 -0700 +data 12 +Second file +M 100644 :1 bar +M 100644 :2 there + +EOF + +test_expect_failure 'no exact-ref revisions included' ' + cd limit-by-paths && + git fast-export master~2..master~1 > output && + test_cmp output expected && + cd .. +' + + test_expect_success 'set-up a few more tags for tag export tests' ' git checkout -f master && HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` && From 8af15d282e59a7f566b5e7eb71caebfc40ca5cd6 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 25 Jun 2009 22:48:33 -0600 Subject: [PATCH 07/41] fast-export: Document the fact that git-rev-list arguments are accepted Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- Documentation/git-fast-export.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 194abdeeba..af2328d401 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -82,6 +82,12 @@ marks the same across runs. allow that. So fake a tagger to be able to fast-import the output. +[git-rev-list-args...]:: + A list of arguments, acceptable to 'git-rev-parse' and + 'git-rev-list', that specifies the specific objects and references + to export. For example, `master\~10..master` causes the + current master reference to be exported along with all objects + added since its 10th ancestor commit. EXAMPLES -------- From 1830d9cb62772c0626297e4bb6e537664283ebfa Mon Sep 17 00:00:00 2001 From: Greg Price Date: Wed, 22 Jul 2009 12:38:58 -0400 Subject: [PATCH 08/41] Fix rebase -p --onto In a rebase with --onto, the correct test for whether we can skip rewriting a commit is if it is already on top of $ONTO, not $UPSTREAM. Without --onto, this distinction does not exist and the behavior does not change. In a situation with two merged branches on a common base X: X---o---o---o---M \ / x---x---x---x Y if we try to move the branches from their base on X to be based on Y, so as to get X Y---o'--o'--o'--M' \ / x'--x'--x'--x' then we fail. The command `git rebase -p --onto Y X M` moves only the first-parent chain, like so: X \ x---x---x---x \ Y---o'--o'--o'--M' because it mistakenly drops the other branch(es) x---x---x---x from the TODO file. This tests and fixes this behavior. Signed-off-by: Greg Price Signed-off-by: Junio C Hamano --- git-rebase--interactive.sh | 2 +- t/t3414-rebase-preserve-onto.sh | 80 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100755 t/t3414-rebase-preserve-onto.sh diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f96d887d23..23ded48322 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -703,7 +703,7 @@ first and then run 'git rebase --continue' again." preserve=t for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -s -f2-) do - if test -f "$REWRITTEN"/$p -a \( $p != $UPSTREAM -o $sha1 = $first_after_upstream \) + if test -f "$REWRITTEN"/$p -a \( $p != $ONTO -o $sha1 = $first_after_upstream \) then preserve=f fi diff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh new file mode 100755 index 0000000000..80019ee072 --- /dev/null +++ b/t/t3414-rebase-preserve-onto.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (c) 2009 Greg Price +# + +test_description='git rebase -p should respect --onto + +In a rebase with --onto, we should rewrite all the commits that +aren'"'"'t on top of $ONTO, even if they are on top of $UPSTREAM. +' +. ./test-lib.sh + +. ../lib-rebase.sh + +# Set up branches like this: +# A1---B1---E1---F1---G1 +# \ \ / +# \ \--C1---D1--/ +# H1 + +test_expect_success 'setup' ' + test_commit A1 && + test_commit B1 && + test_commit C1 && + test_commit D1 && + git reset --hard B1 && + test_commit E1 && + test_commit F1 && + test_merge G1 D1 && + git reset --hard A1 && + test_commit H1 +' + +# Now rebase merge G1 from both branches' base B1, both should move: +# A1---B1---E1---F1---G1 +# \ \ / +# \ \--C1---D1--/ +# \ +# H1---E2---F2---G2 +# \ / +# \--C2---D2--/ + +test_expect_success 'rebase from B1 onto H1' ' + git checkout G1 && + git rebase -p --onto H1 B1 && + test "$(git rev-parse HEAD^1^1^1)" = "$(git rev-parse H1)" && + test "$(git rev-parse HEAD^2^1^1)" = "$(git rev-parse H1)" +' + +# On the other hand if rebase from E1 which is within one branch, +# then the other branch stays: +# A1---B1---E1---F1---G1 +# \ \ / +# \ \--C1---D1--/ +# \ \ +# H1-----F3-----G3 + +test_expect_success 'rebase from E1 onto H1' ' + git checkout G1 && + git rebase -p --onto H1 E1 && + test "$(git rev-parse HEAD^1^1)" = "$(git rev-parse H1)" && + test "$(git rev-parse HEAD^2)" = "$(git rev-parse D1)" +' + +# And the same if we rebase from a commit in the second-parent branch. +# A1---B1---E1---F1----G1 +# \ \ \ / +# \ \--C1---D1-\-/ +# \ \ +# H1------D3------G4 + +test_expect_success 'rebase from C1 onto H1' ' + git checkout G1 && + git rev-list --first-parent --pretty=oneline C1..G1 && + git rebase -p --onto H1 C1 && + test "$(git rev-parse HEAD^2^1)" = "$(git rev-parse H1)" && + test "$(git rev-parse HEAD^1)" = "$(git rev-parse F1)" +' + +test_done From eafb45265bb9fcbee3cc03b451da7e17db9e6be7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 22 Jul 2009 23:07:05 -0700 Subject: [PATCH 09/41] do_one_ref(): null_sha1 check is not about broken ref f8948e2 (remote prune: warn dangling symrefs, 2009-02-08) introduced a more dangerous variant of for_each_ref() family that skips the check for dangling refs, but it also made another unrelated check optional by mistake. The check to see if a ref points at 0{40} is not about brokenness, but is about a possible future plan to represent a deleted ref by writing 40 "0" in a loose ref when there is a stale version of the same ref already in .git/packed-refs, so that we can implement deletion of a ref without having to rewrite the packed refs file excluding the ref being deleted. This check has to live outside of the conditional. Signed-off-by: Junio C Hamano --- refs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/refs.c b/refs.c index bb0762ee2b..3da3c8cefc 100644 --- a/refs.c +++ b/refs.c @@ -531,9 +531,10 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim, { if (strncmp(base, entry->name, trim)) return 0; + /* Is this a "negative ref" that represents a deleted ref? */ + if (is_null_sha1(entry->sha1)) + return 0; if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) { - if (is_null_sha1(entry->sha1)) - return 0; if (!has_sha1_file(entry->sha1)) { error("%s does not point to a valid object!", entry->name); return 0; From 4aacaeb3dc82bb6479e70e120053dc27a399460e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 20 Jul 2009 02:06:24 -0700 Subject: [PATCH 10/41] git svn: fix shallow clone when upstream revision is too new Thanks to Ka-Hing Cheung for the initial bug report and patch: > git-svn uses $ra->get_latest_revnum to find out the latest > revision, but that can be problematic, because get_latest_revnum > returns the latest revnum in the entire repository, not > restricted by whatever URL you used to construct $ra. So if you > do git svn clone -r HEAD svn://blah/blah/trunk, it won't work if > the latest checkin is in one of the branches (it will try to > fetch a rev that doesn't exist in trunk, making the clone > useless). Relying on SVN::Core::INVALID_REVNUM (-1) as the "start" argument to SVN::Ra::get_log() proved unreliable with http(s) URLs so the result of SVN::Ra::get_latest_revnum() is used as the "start" argument instead. Signed-off-by: Eric Wong --- git-svn.perl | 1 + t/t9142-git-svn-shallow-clone.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 t/t9142-git-svn-shallow-clone.sh diff --git a/git-svn.perl b/git-svn.perl index 43c86e85a1..9369acc4dc 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -1647,6 +1647,7 @@ sub fetch_all { my $ra = Git::SVN::Ra->new($url); my $uuid = $ra->get_uuid; my $head = $ra->get_latest_revnum; + $ra->get_log("", $head, 0, 1, 0, 1, sub { $head = $_[1] }); my $base = defined $fetch ? $head : 0; # read the max revs for wildcard expansion (branches/*, tags/*) diff --git a/t/t9142-git-svn-shallow-clone.sh b/t/t9142-git-svn-shallow-clone.sh new file mode 100755 index 0000000000..fd5ad49471 --- /dev/null +++ b/t/t9142-git-svn-shallow-clone.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# +# Copyright (c) 2009 Eric Wong +# + +test_description='git svn shallow clone' +. ./lib-git-svn.sh + +test_expect_success 'setup test repository' ' + svn_cmd mkdir -m "create standard layout" \ + "$svnrepo"/trunk "$svnrepo"/branches "$svnrepo"/tags && + svn_cmd cp -m "branch off trunk" \ + "$svnrepo"/trunk "$svnrepo"/branches/a && + svn_cmd co "$svnrepo"/branches/a && + ( + cd a && + > foo && + svn_cmd add foo && + svn_cmd commit -m "add foo" + ) +' + +start_httpd + +test_expect_success 'clone trunk with "-r HEAD"' ' + git svn clone -r HEAD "$svnrepo/trunk" g && + ( cd g && git rev-parse --symbolic --verify HEAD ) +' + +test_done From e6e4a47ba12bd19ed956251f191b1ea9915f61f8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 23 Jul 2009 10:17:04 -0700 Subject: [PATCH 11/41] git branch: fix performance problem 'git branch' looks at _all_ the refs, and verifies them. Which means that during cold-cache situations with a slow disk (and lots of tags, for example) it can take several very annoying seconds (7.5s according to a report by Carlos R. Mafra). This avoids most of it by simply doing the filtering before looking up the commits, by using the "raw" version of for_each_ref. Reported-by: Carlos R. Mafra Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-branch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/builtin-branch.c b/builtin-branch.c index 91098ca9b1..3784dda090 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -240,6 +240,10 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, if (ARRAY_SIZE(ref_kind) <= i) return 0; + /* Don't add types the caller doesn't want */ + if ((kind & ref_list->kinds) == 0) + return 0; + commit = lookup_commit_reference_gently(sha1, 1); if (!commit) return error("branch '%s' does not point at a commit", refname); @@ -248,10 +252,6 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, if (!is_descendant_of(commit, ref_list->with_commit)) return 0; - /* Don't add types the caller doesn't want */ - if ((kind & ref_list->kinds) == 0) - return 0; - if (merge_filter != NO_FILTER) add_pending_object(&ref_list->revs, (struct object *)commit, refname); @@ -426,7 +426,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str ref_list.with_commit = with_commit; if (merge_filter != NO_FILTER) init_revisions(&ref_list.revs, NULL); - for_each_ref(append_ref, &ref_list); + for_each_rawref(append_ref, &ref_list); if (merge_filter != NO_FILTER) { struct commit *filter; filter = lookup_commit_reference_gently(merge_filter_ref, 0); From 191d1ac435c01e2a7acfb93fb9da8378da90214c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 23 Jul 2009 12:05:34 -0700 Subject: [PATCH 12/41] git branch: avoid unnecessary object lookups They can be expensive in the cold-cache case, so don't bother looking up the commits for all branches unless we really need them for some reason. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-branch.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/builtin-branch.c b/builtin-branch.c index 3784dda090..0e30756b1b 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -191,7 +191,7 @@ struct ref_item { struct ref_list { struct rev_info revs; - int index, alloc, maxwidth; + int index, alloc, maxwidth, verbose; struct ref_item *list; struct commit_list *with_commit; int kinds; @@ -244,17 +244,20 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags, if ((kind & ref_list->kinds) == 0) return 0; - commit = lookup_commit_reference_gently(sha1, 1); - if (!commit) - return error("branch '%s' does not point at a commit", refname); + commit = NULL; + if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) { + commit = lookup_commit_reference_gently(sha1, 1); + if (!commit) + return error("branch '%s' does not point at a commit", refname); - /* Filter with with_commit if specified */ - if (!is_descendant_of(commit, ref_list->with_commit)) - return 0; + /* Filter with with_commit if specified */ + if (!is_descendant_of(commit, ref_list->with_commit)) + return 0; - if (merge_filter != NO_FILTER) - add_pending_object(&ref_list->revs, - (struct object *)commit, refname); + if (merge_filter != NO_FILTER) + add_pending_object(&ref_list->revs, + (struct object *)commit, refname); + } /* Resize buffer */ if (ref_list->index >= ref_list->alloc) { @@ -423,6 +426,7 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str memset(&ref_list, 0, sizeof(ref_list)); ref_list.kinds = kinds; + ref_list.verbose = verbose; ref_list.with_commit = with_commit; if (merge_filter != NO_FILTER) init_revisions(&ref_list.revs, NULL); From 7e9ff00bbe1f437ff492a714758a4f7360feb22b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 23 Jul 2009 12:13:48 -0700 Subject: [PATCH 13/41] git branch: clean up detached branch handling Make the 'show detached branch info' a routine of its own. And in the process, avoid the object lookup that is unnecessary if the current branch isn't detached. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-branch.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/builtin-branch.c b/builtin-branch.c index 0e30756b1b..887fa60fa5 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -191,7 +191,7 @@ struct ref_item { struct ref_list { struct rev_info revs; - int index, alloc, maxwidth, verbose; + int index, alloc, maxwidth, verbose, abbrev; struct ref_item *list; struct commit_list *with_commit; int kinds; @@ -418,15 +418,34 @@ static int calc_maxwidth(struct ref_list *refs) return w; } + +static void show_detached(struct ref_list *ref_list) +{ + struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1); + + if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) { + struct ref_item item; + item.name = xstrdup("(no branch)"); + item.len = strlen(item.name); + item.kind = REF_LOCAL_BRANCH; + item.dest = NULL; + item.commit = head_commit; + if (item.len > ref_list->maxwidth) + ref_list->maxwidth = item.len; + print_ref_item(&item, ref_list->maxwidth, ref_list->verbose, ref_list->abbrev, 1, ""); + free(item.name); + } +} + static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit) { int i; struct ref_list ref_list; - struct commit *head_commit = lookup_commit_reference_gently(head_sha1, 1); memset(&ref_list, 0, sizeof(ref_list)); ref_list.kinds = kinds; ref_list.verbose = verbose; + ref_list.abbrev = abbrev; ref_list.with_commit = with_commit; if (merge_filter != NO_FILTER) init_revisions(&ref_list.revs, NULL); @@ -446,19 +465,8 @@ static void print_ref_list(int kinds, int detached, int verbose, int abbrev, str qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp); detached = (detached && (kinds & REF_LOCAL_BRANCH)); - if (detached && head_commit && - is_descendant_of(head_commit, with_commit)) { - struct ref_item item; - item.name = xstrdup("(no branch)"); - item.len = strlen(item.name); - item.kind = REF_LOCAL_BRANCH; - item.dest = NULL; - item.commit = head_commit; - if (item.len > ref_list.maxwidth) - ref_list.maxwidth = item.len; - print_ref_item(&item, ref_list.maxwidth, verbose, abbrev, 1, ""); - free(item.name); - } + if (detached) + show_detached(&ref_list); for (i = 0; i < ref_list.index; i++) { int current = !detached && From 1ec648278e3a3e5a04dfaac916f68e2f675ff9ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Thu, 23 Jul 2009 17:33:45 +0200 Subject: [PATCH 14/41] Add a test showing that 'git repack' throws away grafted-away parents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bj旦rn Steinbrink Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- t/t7700-repack.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index 87c9b0e121..a4dddb728f 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -149,5 +149,17 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar test_must_fail git show $csha1 ' +test_expect_failure 'objects made unreachable by grafts only are kept' ' + test_tick && + git commit --allow-empty -m "commit 4" && + H0=$(git rev-parse HEAD) && + H1=$(git rev-parse HEAD^) && + H2=$(git rev-parse HEAD^^) && + echo "$H0 $H2" > .git/info/grafts && + git reflog expire --expire=now --expire-unreachable=now --all && + git repack -a -d && + git cat-file -t $H1 + ' + test_done From 7f3140cd23f126e578ccaaea8c2cebe36824a7ac Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Thu, 23 Jul 2009 17:33:49 +0200 Subject: [PATCH 15/41] git repack: keep commits hidden by a graft When you have grafts that pretend that a given commit has different parents than the ones recorded in the commit object, it is dangerous to let 'git repack' remove those hidden parents, as you can easily remove the graft and end up with a broken repository. So let's play it safe and keep those parent objects and everything that is reachable by them, in addition to the grafted parents. As this behavior can only be triggered by git pack-objects, and as that command handles duplicate parents gracefully, we do not bother to cull duplicated parents that may result by using both true and grafted parents. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-pack-objects.txt | 7 ++++++- builtin-pack-objects.c | 4 ++++ cache.h | 2 ++ commit.c | 6 +++++- environment.c | 1 + git-repack.sh | 2 +- t/t7700-repack.sh | 2 +- 7 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index 7d4c1a7556..2e4992970e 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -11,7 +11,8 @@ SYNOPSIS [verse] 'git pack-objects' [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] [--all-progress] - [--revs [--unpacked | --all]*] [--stdout | base-name] < object-list + [--revs [--unpacked | --all]*] [--stdout | base-name] + [--keep-true-parents] < object-list DESCRIPTION @@ -197,6 +198,10 @@ base-name:: to force the version for the generated pack index, and to force 64-bit index entries on objects located above the given offset. +--keep-true-parents:: + With this option, parents that are hidden by grafts are packed + nevertheless. + Author ------ diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 941cc2d73c..527638168b 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -2259,6 +2259,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) die("bad %s", arg); continue; } + if (!strcmp(arg, "--keep-true-parents")) { + grafts_replace_parents = 0; + continue; + } usage(pack_usage); } diff --git a/cache.h b/cache.h index b8503ad91c..e902008297 100644 --- a/cache.h +++ b/cache.h @@ -561,6 +561,8 @@ enum object_creation_mode { extern enum object_creation_mode object_creation_mode; +extern int grafts_replace_parents; + #define GIT_REPO_VERSION 0 extern int repository_format_version; extern int check_repository_format(void); diff --git a/commit.c b/commit.c index aa3b35b6a8..f69525a089 100644 --- a/commit.c +++ b/commit.c @@ -266,7 +266,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) bufptr[47] != '\n') return error("bad parents in commit %s", sha1_to_hex(item->object.sha1)); bufptr += 48; - if (graft) + /* + * The clone is shallow if nr_parent < 0, and we must + * not traverse its real parents even when we unhide them. + */ + if (graft && (graft->nr_parent < 0 || grafts_replace_parents)) continue; new_parent = lookup_commit(parent); if (new_parent) diff --git a/environment.c b/environment.c index 801a005ef1..477d2e4da8 100644 --- a/environment.c +++ b/environment.c @@ -47,6 +47,7 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS #endif enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; +int grafts_replace_parents = 1; /* Parallel index stat data preload? */ int core_preload_index = 0; diff --git a/git-repack.sh b/git-repack.sh index 0868734723..be0c8435dc 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -81,7 +81,7 @@ case ",$all_into_one," in esac args="$args $local $quiet $no_reuse$extra" -names=$(git pack-objects --honor-pack-keep --non-empty --all --reflog $args Date: Fri, 24 Jul 2009 10:17:13 +0200 Subject: [PATCH 16/41] Fix export_marks() error handling. - Don't leak one FILE * on error per export_marks() call. Found with cppcheck and reported by Martin Ettl. - Abort the potentially long for(;idnums.size;) loop on write errors. - Record error if fprintf() fails for reasons not required to set the stream error indicator, such as ENOMEM. - Add a trailing full-stop to error message when fopen() fails. Signed-off-by: Matthias Andree Signed-off-by: Junio C Hamano --- builtin-fast-export.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 6731713223..9091481fd5 100644 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -428,21 +428,27 @@ static void export_marks(char *file) uint32_t mark; struct object_decoration *deco = idnums.hash; FILE *f; + int e = 0; f = fopen(file, "w"); if (!f) - error("Unable to open marks file %s for writing", file); + error("Unable to open marks file %s for writing.", file); for (i = 0; i < idnums.size; i++) { if (deco->base && deco->base->type == 1) { mark = ptr_to_mark(deco->decoration); - fprintf(f, ":%"PRIu32" %s\n", mark, - sha1_to_hex(deco->base->sha1)); + if (fprintf(f, ":%"PRIu32" %s\n", mark, + sha1_to_hex(deco->base->sha1)) < 0) { + e = 1; + break; + } } deco++; } - if (ferror(f) || fclose(f)) + e |= ferror(f); + e |= fclose(f); + if (e) error("Unable to write marks file %s.", file); } From 01ae841ccf3aa5d5331a4e6aed6122fee6617740 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 23 Jul 2009 22:30:07 -0700 Subject: [PATCH 17/41] SunOS grep does not understand -C nor -e The first "grep -C1" test in t7002 does not pass on my SunOS-5.11-i86pc, and that is not because our way to spawn external grep is broken, but because the native grep does not understand -C. It turns out that Peff was also using this option himself because our Makefile doesn't do that automatically. Brandon Casey uses SUNWspro compiler without having to set this, and it turns out that the compiler does not define preprocessor macro __unix__ which made him always use the built-in grep, never an external one. Let's be more explicit and say that we do not use external grep on Suns. Signed-off-by: Junio C Hamano --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c6b81d0125..f88ed3e14d 100644 --- a/Makefile +++ b/Makefile @@ -702,6 +702,7 @@ ifeq ($(uname_S),SunOS) NO_HSTRERROR = YesPlease NO_MKDTEMP = YesPlease OLD_ICONV = UnfortunatelyYes + NO_EXTERNAL_GREP = YesPlease ifeq ($(uname_R),5.8) NO_UNSETENV = YesPlease NO_SETENV = YesPlease From 397f7c6371d309aa399bf32b773397f3c068d0c9 Mon Sep 17 00:00:00 2001 From: Daniel Trstenjak Date: Wed, 22 Jul 2009 10:31:34 +0200 Subject: [PATCH 18/41] Show the presence of untracked files in the bash prompt. Added the envvar GIT_PS1_SHOWUNTRACKEDFILES to 'git-completion.bash'. When set to a nonempty value, then the char '%' will be shown next to the branch name in the bash prompt. Signed-off-by: Daniel Trstenjak Acked-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 887731e830..745b5fb78b 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -44,6 +44,10 @@ # GIT_PS1_SHOWSTASHSTATE to a nonempty value. If something is stashed, # then a '$' will be shown next to the branch name. # +# If you would like to see if there're untracked files, then you can +# set GIT_PS1_SHOWUNTRACKEDFILES to a nonempty value. If there're +# untracked files, then a '%' will be shown next to the branch name. +# # To submit patches: # # *) Read Documentation/SubmittingPatches @@ -132,6 +136,7 @@ __git_ps1 () local w local i local s + local u local c if [ "true" = "$(git rev-parse --is-inside-git-dir 2>/dev/null)" ]; then @@ -156,12 +161,18 @@ __git_ps1 () if [ -n "${GIT_PS1_SHOWSTASHSTATE-}" ]; then git rev-parse --verify refs/stash >/dev/null 2>&1 && s="$" fi + + if [ -n "${GIT_PS1_SHOWUNTRACKEDFILES-}" ]; then + if [ -n "$(git ls-files --others --exclude-standard)" ]; then + u="%" + fi + fi fi if [ -n "${1-}" ]; then - printf "$1" "$c${b##refs/heads/}$w$i$s$r" + printf "$1" "$c${b##refs/heads/}$w$i$s$u$r" else - printf " (%s)" "$c${b##refs/heads/}$w$i$s$r" + printf " (%s)" "$c${b##refs/heads/}$w$i$s$u$r" fi fi } From 302e04ea4d0c0414cedd716de882fa3dbe3480eb Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 23 Jul 2009 07:09:29 -0400 Subject: [PATCH 19/41] send-email: detect cycles in alias expansion With the previous code, an alias cycle like: $ echo 'alias a b' >aliases $ echo 'alias b a' >aliases $ git config sendemail.aliasesfile aliases $ git config sendemail.aliasfiletype mutt would put send-email into an infinite loop. This patch detects the situation and complains to the user. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- git-send-email.perl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index cccbf4517a..f299c2dba2 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -655,13 +655,17 @@ if (!@to) { } sub expand_aliases { - my @cur = @_; - my @last; - do { - @last = @cur; - @cur = map { $aliases{$_} ? @{$aliases{$_}} : $_ } @last; - } while (join(',',@cur) ne join(',',@last)); - return @cur; + return map { expand_one_alias($_) } @_; +} + +my %EXPANDED_ALIASES; +sub expand_one_alias { + my $alias = shift; + if ($EXPANDED_ALIASES{$alias}) { + die "fatal: alias '$alias' expands to itself\n"; + } + local $EXPANDED_ALIASES{$alias} = 1; + return $aliases{$alias} ? expand_aliases(@{$aliases{$alias}}) : $alias; } @to = expand_aliases(@to); From a4c0d463c0a1b38b7af45c1e7dd5608860eb1e28 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Fri, 24 Jul 2009 17:21:43 -0400 Subject: [PATCH 20/41] Make section_name_match start on '[', and return the length on success Signed-off-by: Alex Vandiver Signed-off-by: Junio C Hamano --- config.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/config.c b/config.c index 1682273c12..8d0e549976 100644 --- a/config.c +++ b/config.c @@ -1174,7 +1174,9 @@ write_err_out: static int section_name_match (const char *buf, const char *name) { int i = 0, j = 0, dot = 0; - for (; buf[i] && buf[i] != ']'; i++) { + if (buf[i] != '[') + return 0; + for (i = 1; buf[i] && buf[i] != ']'; i++) { if (!dot && isspace(buf[i])) { dot = 1; if (name[j++] != '.') @@ -1195,7 +1197,17 @@ static int section_name_match (const char *buf, const char *name) if (buf[i] != name[j++]) break; } - return (buf[i] == ']' && name[j] == 0); + if (buf[i] == ']' && name[j] == 0) { + /* + * We match, now just find the right length offset by + * gobbling up any whitespace after it, as well + */ + i++; + for (; buf[i] && isspace(buf[i]); i++) + ; /* do nothing */ + return i; + } + return 0; } /* if new_name == NULL, the section is removed instead */ @@ -1229,7 +1241,8 @@ int git_config_rename_section(const char *old_name, const char *new_name) ; /* do nothing */ if (buf[i] == '[') { /* it's a section */ - if (section_name_match (&buf[i+1], old_name)) { + int offset = section_name_match(&buf[i], old_name); + if (offset > 0) { ret++; if (new_name == NULL) { remove = 1; From 9a5abfc737b18c23d060ff3be1ee8df560b81fa5 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Fri, 24 Jul 2009 17:21:44 -0400 Subject: [PATCH 21/41] After renaming a section, print any trailing variable definitions Signed-off-by: Alex Vandiver Signed-off-by: Junio C Hamano --- config.c | 22 +++++++++++++++++++--- t/t1300-repo-config.sh | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/config.c b/config.c index 8d0e549976..738b24419d 100644 --- a/config.c +++ b/config.c @@ -1237,6 +1237,7 @@ int git_config_rename_section(const char *old_name, const char *new_name) while (fgets(buf, sizeof(buf), config_file)) { int i; int length; + char *output = buf; for (i = 0; buf[i] && isspace(buf[i]); i++) ; /* do nothing */ if (buf[i] == '[') { @@ -1253,14 +1254,29 @@ int git_config_rename_section(const char *old_name, const char *new_name) ret = write_error(lock->filename); goto out; } - continue; + /* + * We wrote out the new section, with + * a newline, now skip the old + * section's length + */ + output += offset + i; + if (strlen(output) > 0) { + /* + * More content means there's + * a declaration to put on the + * next line; indent with a + * tab + */ + output -= 1; + output[0] = '\t'; + } } remove = 0; } if (remove) continue; - length = strlen(buf); - if (write_in_full(out_fd, buf, length) != length) { + length = strlen(output); + if (write_in_full(out_fd, output, length) != length) { ret = write_error(lock->filename); goto out; } diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 43ea283242..8c43dcde8a 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -459,6 +459,28 @@ EOF test_expect_success "rename succeeded" "test_cmp expect .git/config" +cat >> .git/config << EOF +[branch "vier"] z = 1 +EOF + +test_expect_success "rename a section with a var on the same line" \ + 'git config --rename-section branch.vier branch.zwei' + +cat > expect << EOF +# Hallo + #Bello +[branch "zwei"] + x = 1 +[branch "zwei"] + y = 1 +[branch "drei"] +weird +[branch "zwei"] + z = 1 +EOF + +test_expect_success "rename succeeded" "test_cmp expect .git/config" + cat >> .git/config << EOF [branch "zwei"] a = 1 [branch "vier"] EOF From b3601a633801861da9dc1e6b4f7d62b05ca1706c Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 25 Jul 2009 00:51:21 -0700 Subject: [PATCH 22/41] Update release notes for 1.6.4 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.4.txt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Documentation/RelNotes-1.6.4.txt b/Documentation/RelNotes-1.6.4.txt index f578b8186f..b3c0346cc6 100644 --- a/Documentation/RelNotes-1.6.4.txt +++ b/Documentation/RelNotes-1.6.4.txt @@ -38,7 +38,7 @@ Updates since v1.6.3 * We feed iconv with "UTF-8" instead of "utf8"; the former is understood more widely. Similarly updated test scripts to use - encoding names more widely understood (e.g. use "ISO8850-1" instead + encoding names more widely understood (e.g. use "ISO8859-1" instead of "ISO-8859-1"). * Various portability fixes/workarounds for different vintages of @@ -123,8 +123,19 @@ v1.6.3.X series. that chdir around. It now internally records the repository location as an absolute path when autodetected. + * Removing a section with "git config --remove-section", when its + section header has a variable definition on the same line, lost + that variable definition. + + * "git repack" used to faithfully follow grafts and considered true + parents recorded in the commit object unreachable from the commit. + After such a repacking, you cannot remove grafts without corrupting + the repository. + + * "git send-email" did not detect errorneous loops in alias expansion. + --- exec >/var/tmp/1 echo O=$(git describe master) -O=v1.6.4-rc1-7-gbba0fd2 +O=v1.6.4-rc2-17-g130b04a git shortlog --no-merges $O..master ^maint From 422a82f21370fe38b3e926a83b460bf2b1dd13ab Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 25 Jul 2009 01:29:20 -0700 Subject: [PATCH 23/41] Fix severe breakage in "git-apply --whitespace=fix" 735c674 (Trailing whitespace and no newline fix, 2009-07-22) completely broke --whitespace=fix, causing it to lose all the empty lines in a patch. Signed-off-by: Junio C Hamano --- t/t4124-apply-ws-rule.sh | 10 +++++++--- ws.c | 4 ++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index 5698a9a736..fac2093d7f 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -154,7 +154,9 @@ create_patch () { index e69de29..8bd6648 100644 --- a/target +++ b/target - @@ -0,0 +1 @@ + @@ -0,0 +1,3 @@ + +An empty line follows + + +A line with trailing whitespace and no newline_ \ No newline at end of file EOF @@ -162,8 +164,10 @@ create_patch () { test_expect_success 'trailing whitespace & no newline at the end of file' ' >target && - create_patch | git apply --whitespace=fix - && - grep "newline$" target + create_patch >patch-file && + git apply --whitespace=fix patch-file && + grep "newline$" target && + grep "^$" target ' test_done diff --git a/ws.c b/ws.c index 8d855b7fd5..59d0883c1f 100644 --- a/ws.c +++ b/ws.c @@ -262,10 +262,10 @@ int ws_fix_copy(char *dst, const char *src, int len, unsigned ws_rule, int *erro * Strip trailing whitespace */ if (ws_rule & WS_TRAILING_SPACE) { - if (1 < len && src[len - 1] == '\n') { + if (0 < len && src[len - 1] == '\n') { add_nl_to_tail = 1; len--; - if (1 < len && src[len - 1] == '\r') { + if (0 < len && src[len - 1] == '\r') { add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL); len--; } From 54bc13ce5300bf7c2237aba3fd123dd587e56d31 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 18 Jun 2009 19:18:37 -0700 Subject: [PATCH 24/41] t8005: Nobody writes Russian in shift_jis The second and third tests of this script expected that Russian strings are converted between ISO-8859-5 and Shift_JIS in the "blame --porcelain" format output correctly. Sure, many platforms may convert between such a combination, but that is only because one of the base character set of Shift_JIS, JIS X 0208, defines codepoints for Russian characters (among others); I do not think anybody uses Shift_JIS when seriously writing Russian, and it is perfectly understandable if iconv() libraries on some platforms fail converting between this combination, as it does not matter in reality. This patch changes the test to verify Japanese strings are converted correctly between EUC-JP and Shift_JIS in the same procedure. The point of the test is not about verifying the platform's iconv() library, but to see if "git blame" makes correct iconv() library calls when it should. We could instead use ISO-8859-5 and KOI8-R as the combination, because they are both meant to represent Russian, in order to make this test meaningful on more platforms, but we already use Shift_JIS vs EUC-JP combinations to test other programs in our test suite, so this combination is safer from the point of view of the portability. Besides, I do not read nor write Russian; sorry ;-) This change allows tests to pass on my (friend's) Solaris 5.11 box. Signed-off-by: Junio C Hamano --- t/t8005-blame-i18n.sh | 26 +++++++++++++------------- t/t8005/euc-japan.txt | 2 ++ t/t8005/sjis.txt | 4 ++-- t/t8005/utf8.txt | 4 ++-- 4 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 t/t8005/euc-japan.txt diff --git a/t/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh index fcd5c26675..9c1e21a60b 100755 --- a/t/t8005-blame-i18n.sh +++ b/t/t8005-blame-i18n.sh @@ -4,7 +4,7 @@ test_description='git blame encoding conversion' . ./test-lib.sh . "$TEST_DIRECTORY"/t8005/utf8.txt -. "$TEST_DIRECTORY"/t8005/cp1251.txt +. "$TEST_DIRECTORY"/t8005/euc-japan.txt . "$TEST_DIRECTORY"/t8005/sjis.txt test_expect_success 'setup the repository' ' @@ -13,10 +13,10 @@ test_expect_success 'setup the repository' ' git add file && git commit --author "$UTF8_NAME " -m "$UTF8_MSG" && - echo "CP1251 LINE" >> file && + echo "EUC-JAPAN LINE" >> file && git add file && - git config i18n.commitencoding cp1251 && - git commit --author "$CP1251_NAME " -m "$CP1251_MSG" && + git config i18n.commitencoding eucJP && + git commit --author "$EUC_JAPAN_NAME " -m "$EUC_JAPAN_MSG" && echo "SJIS LINE" >> file && git add file && @@ -41,17 +41,17 @@ test_expect_success \ ' cat >expected < actual && test_cmp actual expected @@ -76,8 +76,8 @@ test_expect_success \ cat >expected < Date: Sun, 19 Jul 2009 18:00:52 -0500 Subject: [PATCH 25/41] git svn: add gc command Add a git svn gc command that gzips all unhandled.log files, and removes all index files under .git/svn. Signed-off-by: Robert Allan Zeh Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 4 ++++ git-svn.perl | 33 +++++++++++++++++++++++++++++ t/t9143-git-svn-gc.sh | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100755 t/t9143-git-svn-gc.sh diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 10af599b44..068aa58a5b 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -338,6 +338,10 @@ Any other arguments are passed directly to 'git log' Shows the Subversion externals. Use -r/--revision to specify a specific revision. +'gc':: + Compress $GIT_DIR/svn//unhandled.log files in .git/svn + and remove $GIT_DIR/svn/index files in .git/svn. + 'reset':: Undoes the effects of 'fetch' back to the specified revision. This allows you to re-'fetch' an SVN revision. Normally the diff --git a/git-svn.perl b/git-svn.perl index 9369acc4dc..70159204ce 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -31,6 +31,7 @@ require SVN::Delta; if ($SVN::Core::VERSION lt '1.1.0') { fatal "Need SVN::Core 1.1.0 or better (got $SVN::Core::VERSION)"; } +my $can_compress = eval { require Compress::Zlib; 1}; push @Git::SVN::Ra::ISA, 'SVN::Ra'; push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor'; push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor'; @@ -40,6 +41,7 @@ use IO::File qw//; use File::Basename qw/dirname basename/; use File::Path qw/mkpath/; use File::Spec; +use File::Find; use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/; use IPC::Open3; use Git; @@ -217,6 +219,10 @@ my %cmd = ( "Undo fetches back to the specified SVN revision", { 'revision|r=s' => \$_revision, 'parent|p' => \$_fetch_parent } ], + 'gc' => [ \&cmd_gc, + "Compress unhandled.log files in .git/svn and remove " . + "index files in .git/svn", + {} ], ); my $cmd; @@ -1107,6 +1113,14 @@ sub cmd_reset { print "r$r = $c ($gs->{ref_id})\n"; } +sub cmd_gc { + if (!$can_compress) { + warn "Compress::Zlib could not be found; unhandled.log " . + "files will not be compressed.\n"; + } + find({ wanted => \&gc_directory, no_chdir => 1}, "$ENV{GIT_DIR}/svn"); +} + ########################### utility functions ######################### sub rebase_cmd { @@ -1527,6 +1541,25 @@ sub md5sum { return $md5->hexdigest(); } +sub gc_directory { + if ($can_compress && -f $_ && basename($_) eq "unhandled.log") { + my $out_filename = $_ . ".gz"; + open my $in_fh, "<", $_ or die "Unable to open $_: $!\n"; + binmode $in_fh; + my $gz = Compress::Zlib::gzopen($out_filename, "ab") or + die "Unable to open $out_filename: $!\n"; + + my $res; + while ($res = sysread($in_fh, my $str, 1024)) { + $gz->gzwrite($str) or + die "Unable to write: ".$gz->gzerror()."!\n"; + } + unlink $_ or die "unlink $File::Find::name: $!\n"; + } elsif (-f $_ && basename($_) eq "index") { + unlink $_ or die "unlink $_: $!\n"; + } +} + package Git::SVN; use strict; use warnings; diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh new file mode 100755 index 0000000000..aaa3af014c --- /dev/null +++ b/t/t9143-git-svn-gc.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Copyright (c) 2009 Robert Allan Zeh + +test_description='git svn gc basic tests' + +. ./lib-git-svn.sh + +test_expect_success 'setup directories and test repo' ' + mkdir import && + mkdir tmp && + echo "Sample text for Subversion repository." > import/test.txt && + svn_cmd import -m "import for git svn" import "$svnrepo" > /dev/null + ' + +test_expect_success 'checkout working copy from svn' \ + 'svn_cmd co "$svnrepo" test_wc' + +test_expect_success 'set some properties to create an unhandled.log file' ' + ( + cd test_wc && + svn_cmd propset foo bar test.txt && + svn_cmd commit -m "property set" + )' + +test_expect_success 'Setup repo' 'git svn init "$svnrepo"' + +test_expect_success 'Fetch repo' 'git svn fetch' + +test_expect_success 'make backup copy of unhandled.log' ' + cp .git/svn/git-svn/unhandled.log tmp + ' + +test_expect_success 'git svn gc runs' 'git svn gc' + +test_expect_success 'git svn gc produces a valid gzip file' ' + gunzip .git/svn/git-svn/unhandled.log.gz + ' + +test_expect_success 'git svn gc does not change unhandled.log files' ' + test_cmp .git/svn/git-svn/unhandled.log tmp/unhandled.log + ' + +test_done From 6b48829dbbe06798eded1e7c5f70810940591f79 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 25 Jul 2009 00:00:50 -0700 Subject: [PATCH 26/41] git svn: revert default behavior for --minimize-url This reverts the --minimize-url behavior change that appeared recently in commit 0b2af457a49e3b00d47d556d5301934d27909db8 ("Fix branch detection when repository root is inaccessible"). However, we now allow the option to be turned off by allowing "--no-minimize-url" so people with limited-access setups can still take advantage of the fix in 0b2af457a49e3b00d47d556d5301934d27909db8. Also document the behavior and default settings of minimize-url in the manpage for the first time. This introduces a temporary UI regression to allow t9141 to pass that will be reverted (fixed) in the next commit. Signed-off-by: Eric Wong --- Documentation/git-svn.txt | 11 +++++++++++ git-svn.perl | 7 ++++++- t/t9141-git-svn-multiple-branches.sh | 8 ++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 068aa58a5b..22a0389f1e 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -80,6 +80,17 @@ COMMANDS When passed to 'init' or 'clone' this regular expression will be preserved as a config key. See 'fetch' for a description of '--ignore-paths'. +--no-minimize-url;; + When tracking multiple directories (using --stdlayout, + --branches, or --tags options), git svn will attempt to connect + to the root (or highest allowed level) of the Subversion + repository. This default allows better tracking of history if + entire projects are moved within a repository, but may cause + issues on repositories where read access restrictions are in + place. Passing '--no-minimize-url' will allow git svn to + accept URLs as-is without attempting to connect to a higher + level directory. This option is off by default when only + one URL/branch is tracked (it would do little good). 'fetch':: Fetch unfetched revisions from the Subversion remote we are diff --git a/git-svn.perl b/git-svn.perl index 70159204ce..10b77ad34c 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -19,6 +19,7 @@ $ENV{GIT_DIR} ||= '.git'; $Git::SVN::default_repo_id = 'svn'; $Git::SVN::default_ref_id = $ENV{GIT_SVN_ID} || 'git-svn'; $Git::SVN::Ra::_log_window_size = 100; +$Git::SVN::_minimize_url = 'unset'; $Git::SVN::Log::TZ = $ENV{TZ}; $ENV{TZ} = 'UTC'; @@ -100,7 +101,7 @@ my %init_opts = ( 'template=s' => \$_template, 'shared:s' => \$_shared, 'trunk|T=s' => \$_trunk, 'tags|t=s@' => \@_tags, 'branches|b=s@' => \@_branches, 'prefix=s' => \$_prefix, 'stdlayout|s' => \$_stdlayout, - 'minimize-url|m' => \$Git::SVN::_minimize_url, + 'minimize-url|m!' => \$Git::SVN::_minimize_url, 'no-metadata' => sub { $icv{noMetadata} = 1 }, 'use-svm-props' => sub { $icv{useSvmProps} = 1 }, 'use-svnsync-props' => sub { $icv{useSvnsyncProps} = 1 }, @@ -399,6 +400,10 @@ sub cmd_init { init_subdir(@_); do_git_init_db(); + if ($Git::SVN::_minimize_url eq 'unset') { + $Git::SVN::_minimize_url = 0; + } + Git::SVN->init($url); } diff --git a/t/t9141-git-svn-multiple-branches.sh b/t/t9141-git-svn-multiple-branches.sh index 3cd06718eb..cb9a6d229d 100755 --- a/t/t9141-git-svn-multiple-branches.sh +++ b/t/t9141-git-svn-multiple-branches.sh @@ -99,22 +99,22 @@ test_expect_success 'Multiple branch or tag paths require -d' ' test_expect_success 'create new branches and tags' ' ( cd git_project && - git svn branch -m "New branch 1" -d b_one New1 ) && + git svn branch -m "New branch 1" -d project/b_one New1 ) && ( cd svn_project && svn_cmd up && test -e b_one/New1/a.file ) && ( cd git_project && - git svn branch -m "New branch 2" -d b_two New2 ) && + git svn branch -m "New branch 2" -d project/b_two New2 ) && ( cd svn_project && svn_cmd up && test -e b_two/New2/a.file ) && ( cd git_project && - git svn branch -t -m "New tag 1" -d tags_A Tag1 ) && + git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) && ( cd svn_project && svn_cmd up && test -e tags_A/Tag1/a.file ) && ( cd git_project && - git svn tag -m "New tag 2" -d tags_B Tag2 ) && + git svn tag -m "New tag 2" -d project/tags_B Tag2 ) && ( cd svn_project && svn_cmd up && test -e tags_B/Tag2/a.file ) ' From eaa14ff8c7dbe51dfdfe7e2d9ede839fc62dcf52 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 25 Jul 2009 01:36:06 -0700 Subject: [PATCH 27/41] git svn: the branch command no longer needs the full path This was introduced in 0b2af457a49e3b00d47d556d5301934d27909db8 ("Fix branch detection when repository root is inaccessible") but reintroduced in the previous commit. Signed-off-by: Eric Wong --- git-svn.perl | 19 ++++++++++++++++--- t/t9141-git-svn-multiple-branches.sh | 8 ++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/git-svn.perl b/git-svn.perl index 10b77ad34c..9808597a18 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -666,9 +666,22 @@ sub cmd_branch { } } unless (defined $glob) { - die "Unknown ", - $_tag ? "tag" : "branch", - " destination $_branch_dest\n"; + my $dest_re = qr/\b\Q$_branch_dest\E\b/; + foreach my $g (@{$allglobs}) { + $g->{path}->{left} =~ /$dest_re/ or next; + if (defined $glob) { + die "Ambiguous destination: ", + $_branch_dest, "\nmatches both '", + $glob->{path}->{left}, "' and '", + $g->{path}->{left}, "'\n"; + } + $glob = $g; + } + unless (defined $glob) { + die "Unknown ", + $_tag ? "tag" : "branch", + " destination $_branch_dest\n"; + } } } my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/}; diff --git a/t/t9141-git-svn-multiple-branches.sh b/t/t9141-git-svn-multiple-branches.sh index cb9a6d229d..3cd06718eb 100755 --- a/t/t9141-git-svn-multiple-branches.sh +++ b/t/t9141-git-svn-multiple-branches.sh @@ -99,22 +99,22 @@ test_expect_success 'Multiple branch or tag paths require -d' ' test_expect_success 'create new branches and tags' ' ( cd git_project && - git svn branch -m "New branch 1" -d project/b_one New1 ) && + git svn branch -m "New branch 1" -d b_one New1 ) && ( cd svn_project && svn_cmd up && test -e b_one/New1/a.file ) && ( cd git_project && - git svn branch -m "New branch 2" -d project/b_two New2 ) && + git svn branch -m "New branch 2" -d b_two New2 ) && ( cd svn_project && svn_cmd up && test -e b_two/New2/a.file ) && ( cd git_project && - git svn branch -t -m "New tag 1" -d project/tags_A Tag1 ) && + git svn branch -t -m "New tag 1" -d tags_A Tag1 ) && ( cd svn_project && svn_cmd up && test -e tags_A/Tag1/a.file ) && ( cd git_project && - git svn tag -m "New tag 2" -d project/tags_B Tag2 ) && + git svn tag -m "New tag 2" -d tags_B Tag2 ) && ( cd svn_project && svn_cmd up && test -e tags_B/Tag2/a.file ) ' From 5af9b77b553eae80a14dd06f14bf1ee1268a0288 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 25 Jul 2009 02:11:39 -0700 Subject: [PATCH 28/41] t9142: stop httpd after the test Otherwise it would fail in subsequent runs if the same SVN_HTTPD_PORT was used. Signed-off-by: Eric Wong --- t/t9142-git-svn-shallow-clone.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/t9142-git-svn-shallow-clone.sh b/t/t9142-git-svn-shallow-clone.sh index fd5ad49471..1236accd99 100755 --- a/t/t9142-git-svn-shallow-clone.sh +++ b/t/t9142-git-svn-shallow-clone.sh @@ -27,4 +27,6 @@ test_expect_success 'clone trunk with "-r HEAD"' ' ( cd g && git rev-parse --symbolic --verify HEAD ) ' +stop_httpd + test_done From 884cce5bd042e67a0d2a1a9317f8435634486ad1 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 25 Jul 2009 02:29:28 -0700 Subject: [PATCH 29/41] git svn: avoid escaping '/' when renaming/copying files Timothy Schaeffer reported the following: > Git-svn has been giving me the following error for some time > when calling "git svn dcommit": > > RA layer request failed: PROPFIND request failed on > '/svn/stf/branches/dev/sw%2Fdpemu%2Finclude%2FNetCnxn.h': PROPFIND of > '/svn/stf/branches/dev/sw%2Fdpemu%2Finclude%2FNetCnxn.h': 302 Found > (https://oursvnrepo.net) at /usr/local/libexec/git-core/git-svn line 508 > > This only occurred when git detected a rename or copy. > > Following the lead into git-svn.perl, > and noticing that some of the '/'s in the path were hex-encoded > and some were not, > I changed the regex used to find chars > to hex-encode in the relative part of the path > to exclude '/'. > It works, so far. > I have included a patch. While this has previous not been a problem in my experience, newer versions of SVN may be stricter and this does not introduce regressions in t9115. Signed-off-by: Eric Wong --- git-svn.perl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index 9808597a18..fd7232cf6d 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -4005,7 +4005,7 @@ sub repo_path { sub url_path { my ($self, $path) = @_; if ($self->{url} =~ m#^https?://#) { - $path =~ s/([^~a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg; + $path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf("%%%02x",ord($1))!eg; } $self->{url} . '/' . $self->repo_path($path); } From 71c020c53ec472b04678237d8fe5687f2299db2a Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sat, 25 Jul 2009 14:06:50 +0200 Subject: [PATCH 30/41] Disable asciidoc 8.4.1+ semantics for `{plus}` and friends asciidoc 8.4.1 changed the semantics of inline backtick quoting so that they disable parsing of inline constructs, i.e., Input: `{plus}` Pre 8.4.1: + Post 8.4.1: {plus} Fix this by defining the asciidoc attribute 'no-inline-literal' (which, per the 8.4.1 changelog, is the toggle to return to the old behaviour) when under ASCIIDOC8. Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- Documentation/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Makefile b/Documentation/Makefile index 7a8037f586..06b0c57b95 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -84,7 +84,7 @@ endif # ifdef ASCIIDOC8 -ASCIIDOC_EXTRA += -a asciidoc7compatible +ASCIIDOC_EXTRA += -a asciidoc7compatible -a no-inline-literal endif ifdef DOCBOOK_XSL_172 ASCIIDOC_EXTRA += -a git-asciidoc-no-roff From 5f8b2cbacd3bad38d0ae4d358fe9b34e98190935 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 25 Jul 2009 13:14:16 -0700 Subject: [PATCH 31/41] git svn: make minimize URL more reliable over http(s) In addition to path-based restrictions, Subversion servers over http(s) may have access controls implemented via the LimitExcept directive in Apache. In some cases, LimitExcept may be (arguably) misconfigured to not allow REPORT requests while allowing OPTIONS and PROPFIND. This caused problems with our existing minimize_url logic that only issued OPTIONS and PROPFIND requests when connecting and using SVN::Ra::get_latest_revnum. We now call SVN::Ra::get_log if get_latest_revnum succeeds, resulting in a REPORT request being sent. This will increase our chances of tripping access controls before we start attempting to fetch history. Signed-off-by: Eric Wong --- git-svn.perl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index fd7232cf6d..d075810724 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -4831,7 +4831,11 @@ sub minimize_url { my $c = ''; do { $url .= "/$c" if length $c; - eval { (ref $self)->new($url)->get_latest_revnum }; + eval { + my $ra = (ref $self)->new($url); + my $latest = $ra->get_latest_revnum; + $ra->get_log("", $latest, 0, 1, 0, 1, sub {}); + }; } while ($@ && ($c = shift @components)); $url; } From 2ceb639f93d4ca05467ec34f49de8b6ceb0deb03 Mon Sep 17 00:00:00 2001 From: Nanako Shiraishi Date: Sat, 25 Jul 2009 09:28:50 +0900 Subject: [PATCH 32/41] Documentation/config.txt: a variable can be defined on the section header line Signed-off-by: Nanako Shiraishi Signed-off-by: Junio C Hamano --- Documentation/config.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 6857d2f4a9..c6f09f801a 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -49,7 +49,8 @@ There is also a case insensitive alternative `[section.subsection]` syntax. In this syntax, subsection names follow the same restrictions as for section names. -All the other lines are recognized as setting variables, in the form +All the other lines (and the remainder of the line after the section +header) are recognized as setting variables, in the form 'name = value'. If there is no equal sign on the line, the entire line is taken as 'name' and the variable is recognized as boolean "true". The variable names are case-insensitive and only alphanumeric From d8f7be2ebcb7e3ec40269080a9ab9a28bc06ba17 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 26 Jul 2009 00:04:50 -0700 Subject: [PATCH 33/41] GIT 1.6.4-rc3 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.4.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Documentation/RelNotes-1.6.4.txt b/Documentation/RelNotes-1.6.4.txt index b3c0346cc6..0fbc410428 100644 --- a/Documentation/RelNotes-1.6.4.txt +++ b/Documentation/RelNotes-1.6.4.txt @@ -32,7 +32,8 @@ Updates since v1.6.3 * git-svn updates, including a new --authors-prog option to map author names by invoking an external program, 'git svn reset' to unwind - 'git svn fetch', support for more than one branches, etc. + 'git svn fetch', support for more than one branches, documenting + of the useful --minimize-url feature, new "git svn gc" command, etc. (portability) @@ -75,7 +76,7 @@ Updates since v1.6.3 * "git imap-send" is IPv6 aware. - * "git log --graph" draws graphs more compactly by using horizonal lines + * "git log --graph" draws graphs more compactly by using horizontal lines when able. * "git log --decorate" shows shorter refnames by stripping well-known @@ -105,6 +106,8 @@ Updates since v1.6.3 * A major part of the "git bisect" wrapper has moved to C. + * Formatting with the new version of AsciiDoc 8.4.1 is now supported. + Fixes since v1.6.3 ------------------ @@ -132,10 +135,10 @@ v1.6.3.X series. After such a repacking, you cannot remove grafts without corrupting the repository. - * "git send-email" did not detect errorneous loops in alias expansion. + * "git send-email" did not detect erroneous loops in alias expansion. --- exec >/var/tmp/1 echo O=$(git describe master) -O=v1.6.4-rc2-17-g130b04a +O=v1.6.4-rc2-31-g2ceb639 git shortlog --no-merges $O..master ^maint From e24c76bf09576e0d197db1e40dff655a75e9efe1 Mon Sep 17 00:00:00 2001 From: Sean Estabrooks Date: Sat, 18 Jul 2009 09:45:44 -0700 Subject: [PATCH 34/41] Trivial path quoting fixes in git-instaweb Bodo Schlecht noticed that Instaweb didn't propely quote all path instances in the Apache config file it generated. Acked-by: Eric Wong Signed-off-by: Junio C Hamano --- git-instaweb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-instaweb.sh b/git-instaweb.sh index 5f4419b69b..32f6496b0d 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -256,7 +256,7 @@ apache2_conf () { mkdir -p "$GIT_DIR/gitweb/logs" bind= test x"$local" = xtrue && bind='127.0.0.1:' - echo 'text/css css' > $fqgitdir/mime.types + echo 'text/css css' > "$fqgitdir/mime.types" cat > "$conf" <> "$conf" < Date: Sun, 26 Jul 2009 03:01:52 -0700 Subject: [PATCH 35/41] t9143: do not fail if Compress::Zlib is missing "git svn gc" will not compress unhandled.log files if Compress::Zlib is missing. However, leftover index files should always be removed, so add a test for this behavior as well. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- t/t9143-git-svn-gc.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh index aaa3af014c..f2ba2d1da3 100755 --- a/t/t9143-git-svn-gc.sh +++ b/t/t9143-git-svn-gc.sh @@ -31,11 +31,20 @@ test_expect_success 'make backup copy of unhandled.log' ' cp .git/svn/git-svn/unhandled.log tmp ' +test_expect_success 'create leftover index' '> .git/svn/git-svn/index' + test_expect_success 'git svn gc runs' 'git svn gc' -test_expect_success 'git svn gc produces a valid gzip file' ' - gunzip .git/svn/git-svn/unhandled.log.gz - ' +test_expect_success 'git svn index removed' '! test -f .git/svn/git-svn/index' + +if perl -MCompress::Zlib -e 0 2>/dev/null +then + test_expect_success 'git svn gc produces a valid gzip file' ' + gunzip .git/svn/git-svn/unhandled.log.gz + ' +else + say "Perl Compress::Zlib unavailable, skipping gunzip test" +fi test_expect_success 'git svn gc does not change unhandled.log files' ' test_cmp .git/svn/git-svn/unhandled.log tmp/unhandled.log From 02944cc4929c6a7438dbde9216f9ebb193f1ae81 Mon Sep 17 00:00:00 2001 From: Michael J Gruber Date: Tue, 28 Jul 2009 16:42:15 +0200 Subject: [PATCH 36/41] git-rerere.txt: Clarify ambiguity of the config variable Use the less ambiguous "set variable foo in order to enable bar" rather than "set variable foo to enable bar" which may trick users into assuming that "enable" is a good value for "foo". Signed-off-by: Michael J Gruber Signed-off-by: Junio C Hamano --- Documentation/git-rerere.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index a53c3cd35b..7dd515b8cc 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -23,7 +23,7 @@ on the initial manual merge, and applying previously recorded hand resolutions to their corresponding automerge results. [NOTE] -You need to set the configuration variable rerere.enabled to +You need to set the configuration variable rerere.enabled in order to enable this command. From f552e51ef9d376c17fa707b7af9582108f4ec81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20K=C3=A5gedal?= Date: Tue, 28 Jul 2009 10:32:18 +0200 Subject: [PATCH 37/41] Update the documentation of the raw diff output format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This includes mentioning the initial hash output of diff-tree, and changes the header to "raw output format" which is more descriptive. Signed-off-by: David K奪gedal Signed-off-by: Junio C Hamano --- Documentation/diff-format.txt | 8 +++++++- Documentation/git-diff-files.txt | 3 +-- Documentation/git-diff-index.txt | 2 -- Documentation/git-diff-tree.txt | 3 +-- Documentation/git-diff.txt | 3 +-- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index 1eeb1c7683..b71712473e 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -1,4 +1,7 @@ -The output format from "git-diff-index", "git-diff-tree", +Raw output format +----------------- + +The raw output format from "git-diff-index", "git-diff-tree", "git-diff-files" and "git diff --raw" are very similar. These commands all compare two sets of things; what is @@ -16,6 +19,9 @@ git-diff-tree [-r] [...]:: git-diff-files [...]:: compares the index and the files on the filesystem. +The "git-diff-tree" command begins its ouput by printing the hash of +what is being compared. After that, all the commands print one output +line per changed file. An output line is formatted this way: diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt index c526141564..4ef03578eb 100644 --- a/Documentation/git-diff-files.txt +++ b/Documentation/git-diff-files.txt @@ -43,8 +43,7 @@ omit diff output for unmerged entries and just show "Unmerged". -q:: Remain silent even on nonexistent files -Output format -------------- + include::diff-format.txt[] diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt index 26920d4f63..8b9ed29299 100644 --- a/Documentation/git-diff-index.txt +++ b/Documentation/git-diff-index.txt @@ -34,8 +34,6 @@ include::diff-options.txt[] 'git-diff-index' say that all non-checked-out files are up to date. -Output format -------------- include::diff-format.txt[] Operating Modes diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 23b7abd3c6..f2cef1260b 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -159,8 +159,7 @@ HEAD commits it finds, which is even more interesting. in case you care). -Output format -------------- + include::diff-format.txt[] diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index a2f192fb75..0ac711230e 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -84,8 +84,7 @@ include::diff-options.txt[] the diff to the named paths (you can give directory names and get diff for all files under them). -Output format -------------- + include::diff-format.txt[] EXAMPLES From 33016c491367c5144b3007927cd76492ac193d16 Mon Sep 17 00:00:00 2001 From: Tom Grennan Date: Tue, 28 Jul 2009 18:30:02 -0700 Subject: [PATCH 38/41] request-pull: allow ls-remote to notice remote.$nickname.uploadpack The location to pull from should be converted from the configured nickname to URL in the message, but ls-remote should be fed the nickname so that the command uses remote.$nickname.* variables, most notably "uploadpack". Signed-off-by: Tom Grennan Signed-off-by: Junio C Hamano --- git-request-pull.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-request-pull.sh b/git-request-pull.sh index 5917773240..fd95beadab 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -28,13 +28,13 @@ headrev=`git rev-parse --verify "$head"^0` || exit merge_base=`git merge-base $baserev $headrev` || die "fatal: No commits in common between $base and $head" -url=$(get_remote_url "$url") branch=$(git ls-remote "$url" \ | sed -n -e "/^$headrev refs.heads./{ s/^.* refs.heads.// p q }") +url=$(get_remote_url "$url") if [ -z "$branch" ]; then echo "warn: No branch of $url is at:" >&2 git log --max-count=1 --pretty='tformat:warn: %h: %s' $headrev >&2 From 5c6d8bb29043a3e53c84f1782392a4d71dd10ff9 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 30 May 2009 22:08:02 -0700 Subject: [PATCH 39/41] config.txt: document add.ignore-errors Use the description of "--ignore-errors" from git-add.txt as inspiration. Signed-off-by: Stephen Boyd Signed-off-by: Junio C Hamano --- Documentation/config.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index c06eca43d7..ae0e5db50c 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -438,6 +438,11 @@ On some file system/operating system combinations, this is unreliable. Set this config setting to 'rename' there; However, This will remove the check that makes sure that existing object files will not get overwritten. +add.ignore-errors:: + Tells 'git-add' to continue adding files when some files cannot be + added due to indexing errors. Equivalent to the '--ignore-errors' + option of linkgit:git-add[1]. + alias.*:: Command aliases for the linkgit:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation From e276f018f2c1f0fc962fbe44a36708d1cdebada8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 28 Jul 2009 23:52:58 -0700 Subject: [PATCH 40/41] GIT 1.6.3.4 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.3.4.txt | 36 ++++++++++++++++++++++++++++++ GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 Documentation/RelNotes-1.6.3.4.txt diff --git a/Documentation/RelNotes-1.6.3.4.txt b/Documentation/RelNotes-1.6.3.4.txt new file mode 100644 index 0000000000..cad461bc76 --- /dev/null +++ b/Documentation/RelNotes-1.6.3.4.txt @@ -0,0 +1,36 @@ +GIT v1.6.3.4 Release Notes +========================== + +Fixes since v1.6.3.3 +-------------------- + + * "git add --no-ignore-errors" did not override configured + add.ignore-errors configuration. + + * "git apply --whitespace=fix" did not fix trailing whitespace on an + incomplete line. + + * "git branch" opened too many commit objects unnecessarily. + + * "git checkout -f $commit" with a path that is a file (or a symlink) in + the work tree to a commit that has a directory at the path issued an + unnecessary error message. + + * "git diff -c/--cc" was very inefficient in coalescing the removed lines + shared between parents. + + * "git diff -c/--cc" showed removed lines at the beginning of a file + incorrectly. + + * "git remote show nickname" did not honor configured + remote.nickname.uploadpack when inspecting the branches at the remote. + + * "git request-pull" when talking to the terminal for a preview + showed some of the output in the pager. + + * "git request-pull start nickname [end]" did not honor configured + remote.nickname.uploadpack when it ran git-ls-remote against the remote + repository to learn the current tip of branches. + +Includes other documentation updates and minor fixes. + diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 902bfbf4ef..a56dcb26e7 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.3.3 +DEF_VER=v1.6.3.4 LF=' ' diff --git a/RelNotes b/RelNotes index 392186f0dc..03c996d22a 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes-1.6.3.3.txt \ No newline at end of file +Documentation/RelNotes-1.6.3.4.txt \ No newline at end of file From 0a53e9ddeaddad63ad106860237bbf53411d11a7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 29 Jul 2009 00:32:42 -0700 Subject: [PATCH 41/41] GIT 1.6.4 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.4.txt | 15 +++++++++------ Documentation/git.txt | 5 +++++ GIT-VERSION-GEN | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Documentation/RelNotes-1.6.4.txt b/Documentation/RelNotes-1.6.4.txt index 0fbc410428..7a904419f7 100644 --- a/Documentation/RelNotes-1.6.4.txt +++ b/Documentation/RelNotes-1.6.4.txt @@ -67,6 +67,12 @@ Updates since v1.6.3 * "git cvsexportcommit" learned -k option to stop CVS keywords expansion + * "git fast-export" learned to handle history simplification more + gracefully. + + * "git fast-export" learned an option --tag-of-filtered-object to handle + dangling tags resulting from history simplification more usefully. + * "git grep" learned -p option to show the location of the match using the same context hunk marker "git diff" uses. @@ -130,15 +136,12 @@ v1.6.3.X series. section header has a variable definition on the same line, lost that variable definition. + * "git rebase -p --onto" used to always leave side branches of a merge + intact, even when both branches are subject to rewriting. + * "git repack" used to faithfully follow grafts and considered true parents recorded in the commit object unreachable from the commit. After such a repacking, you cannot remove grafts without corrupting the repository. * "git send-email" did not detect erroneous loops in alias expansion. - ---- -exec >/var/tmp/1 -echo O=$(git describe master) -O=v1.6.4-rc2-31-g2ceb639 -git shortlog --no-merges $O..master ^maint diff --git a/Documentation/git.txt b/Documentation/git.txt index 67bc0b3905..5fd5953e29 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,6 +43,11 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: +* link:v1.6.4/git.html[documentation for release 1.6.4] + +* release notes for + link:RelNotes-1.6.4.txt[1.6.4]. + * link:v1.6.3.4/git.html[documentation for release 1.6.3.4] * release notes for diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 39cde784c9..d8ae315140 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.6.3.GIT +DEF_VER=v1.6.4 LF=' '