From 06aaaa0bf70fe37d198893f4e25fa73b6516f8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Wed, 1 Oct 2008 11:04:01 +0700 Subject: [PATCH 01/52] Extend index to save more flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The on-disk format of index only saves 16 bit flags, nearly all have been used. The last bit (CE_EXTENDED) is used to for future extension. This patch extends index entry format to save more flags in future. The new entry format will be used when CE_EXTENDED bit is 1. Because older implementation may not understand CE_EXTENDED bit and misread the new format, if there is any extended entry in index, index header version will turn 3, which makes it incompatible for older git. If there is none, header version will return to 2 again. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Shawn O. Pearce --- cache.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---- read-cache.c | 51 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 95 insertions(+), 14 deletions(-) diff --git a/cache.h b/cache.h index 991544cf0b..964f7e31cb 100644 --- a/cache.h +++ b/cache.h @@ -115,6 +115,26 @@ struct ondisk_cache_entry { char name[FLEX_ARRAY]; /* more */ }; +/* + * This struct is used when CE_EXTENDED bit is 1 + * The struct must match ondisk_cache_entry exactly from + * ctime till flags + */ +struct ondisk_cache_entry_extended { + struct cache_time ctime; + struct cache_time mtime; + unsigned int dev; + unsigned int ino; + unsigned int mode; + unsigned int uid; + unsigned int gid; + unsigned int size; + unsigned char sha1[20]; + unsigned short flags; + unsigned short flags2; + char name[FLEX_ARRAY]; /* more */ +}; + struct cache_entry { unsigned int ce_ctime; unsigned int ce_mtime; @@ -136,7 +156,15 @@ struct cache_entry { #define CE_VALID (0x8000) #define CE_STAGESHIFT 12 -/* In-memory only */ +/* + * Range 0xFFFF0000 in ce_flags is divided into + * two parts: in-memory flags and on-disk ones. + * Flags in CE_EXTENDED_FLAGS will get saved on-disk + * if you want to save a new flag, add it in + * CE_EXTENDED_FLAGS + * + * In-memory only flags + */ #define CE_UPDATE (0x10000) #define CE_REMOVE (0x20000) #define CE_UPTODATE (0x40000) @@ -145,6 +173,24 @@ struct cache_entry { #define CE_HASHED (0x100000) #define CE_UNHASHED (0x200000) +/* + * Extended on-disk flags + */ +/* CE_EXTENDED2 is for future extension */ +#define CE_EXTENDED2 0x80000000 + +#define CE_EXTENDED_FLAGS (0) + +/* + * Safeguard to avoid saving wrong flags: + * - CE_EXTENDED2 won't get saved until its semantic is known + * - Bits in 0x0000FFFF have been saved in ce_flags already + * - Bits in 0x003F0000 are currently in-memory flags + */ +#if CE_EXTENDED_FLAGS & 0x803FFFFF +#error "CE_EXTENDED_FLAGS out of range" +#endif + /* * Copy the sha1 and stat state of a cache entry from one to * another. But we never change the name, or the hash state! @@ -177,7 +223,9 @@ static inline size_t ce_namelen(const struct cache_entry *ce) } #define ce_size(ce) cache_entry_size(ce_namelen(ce)) -#define ondisk_ce_size(ce) ondisk_cache_entry_size(ce_namelen(ce)) +#define ondisk_ce_size(ce) (((ce)->ce_flags & CE_EXTENDED) ? \ + ondisk_cache_entry_extended_size(ce_namelen(ce)) : \ + ondisk_cache_entry_size(ce_namelen(ce))) #define ce_stage(ce) ((CE_STAGEMASK & (ce)->ce_flags) >> CE_STAGESHIFT) #define ce_uptodate(ce) ((ce)->ce_flags & CE_UPTODATE) #define ce_mark_uptodate(ce) ((ce)->ce_flags |= CE_UPTODATE) @@ -220,8 +268,10 @@ static inline int ce_to_dtype(const struct cache_entry *ce) (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \ S_ISLNK(mode) ? S_IFLNK : S_ISDIR(mode) ? S_IFDIR : S_IFGITLINK) -#define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7) -#define ondisk_cache_entry_size(len) ((offsetof(struct ondisk_cache_entry,name) + (len) + 8) & ~7) +#define flexible_size(STRUCT,len) ((offsetof(struct STRUCT,name) + (len) + 8) & ~7) +#define cache_entry_size(len) flexible_size(cache_entry,len) +#define ondisk_cache_entry_size(len) flexible_size(ondisk_cache_entry,len) +#define ondisk_cache_entry_extended_size(len) flexible_size(ondisk_cache_entry_extended,len) struct index_state { struct cache_entry **cache; diff --git a/read-cache.c b/read-cache.c index c229fd4d0d..ea262fc37e 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1098,7 +1098,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) if (hdr->hdr_signature != htonl(CACHE_SIGNATURE)) return error("bad signature"); - if (hdr->hdr_version != htonl(2)) + if (hdr->hdr_version != htonl(2) && hdr->hdr_version != htonl(3)) return error("bad index version"); git_SHA1_Init(&c); git_SHA1_Update(&c, hdr, size - 20); @@ -1133,6 +1133,7 @@ int read_index(struct index_state *istate) static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_entry *ce) { size_t len; + const char *name; ce->ce_ctime = ntohl(ondisk->ctime.sec); ce->ce_mtime = ntohl(ondisk->mtime.sec); @@ -1145,19 +1146,31 @@ static void convert_from_disk(struct ondisk_cache_entry *ondisk, struct cache_en /* On-disk flags are just 16 bits */ ce->ce_flags = ntohs(ondisk->flags); - /* For future extension: we do not understand this entry yet */ - if (ce->ce_flags & CE_EXTENDED) - die("Unknown index entry format"); hashcpy(ce->sha1, ondisk->sha1); len = ce->ce_flags & CE_NAMEMASK; + + if (ce->ce_flags & CE_EXTENDED) { + struct ondisk_cache_entry_extended *ondisk2; + int extended_flags; + ondisk2 = (struct ondisk_cache_entry_extended *)ondisk; + extended_flags = ntohs(ondisk2->flags2) << 16; + /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */ + if (extended_flags & ~CE_EXTENDED_FLAGS) + die("Unknown index entry format %08x", extended_flags); + ce->ce_flags |= extended_flags; + name = ondisk2->name; + } + else + name = ondisk->name; + if (len == CE_NAMEMASK) - len = strlen(ondisk->name); + len = strlen(name); /* * NEEDSWORK: If the original index is crafted, this copy could * go unchecked. */ - memcpy(ce->name, ondisk->name, len + 1); + memcpy(ce->name, name, len + 1); } static inline size_t estimate_cache_size(size_t ondisk_size, unsigned int entries) @@ -1417,6 +1430,7 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce) { int size = ondisk_ce_size(ce); struct ondisk_cache_entry *ondisk = xcalloc(1, size); + char *name; ondisk->ctime.sec = htonl(ce->ce_ctime); ondisk->ctime.nsec = 0; @@ -1430,7 +1444,15 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce) ondisk->size = htonl(ce->ce_size); hashcpy(ondisk->sha1, ce->sha1); ondisk->flags = htons(ce->ce_flags); - memcpy(ondisk->name, ce->name, ce_namelen(ce)); + if (ce->ce_flags & CE_EXTENDED) { + struct ondisk_cache_entry_extended *ondisk2; + ondisk2 = (struct ondisk_cache_entry_extended *)ondisk; + ondisk2->flags2 = htons((ce->ce_flags & CE_EXTENDED_FLAGS) >> 16); + name = ondisk2->name; + } + else + name = ondisk->name; + memcpy(name, ce->name, ce_namelen(ce)); return ce_write(c, fd, ondisk, size); } @@ -1439,16 +1461,25 @@ int write_index(const struct index_state *istate, int newfd) { git_SHA_CTX c; struct cache_header hdr; - int i, err, removed; + int i, err, removed, extended; struct cache_entry **cache = istate->cache; int entries = istate->cache_nr; - for (i = removed = 0; i < entries; i++) + for (i = removed = extended = 0; i < entries; i++) { if (cache[i]->ce_flags & CE_REMOVE) removed++; + /* reduce extended entries if possible */ + cache[i]->ce_flags &= ~CE_EXTENDED; + if (cache[i]->ce_flags & CE_EXTENDED_FLAGS) { + extended++; + cache[i]->ce_flags |= CE_EXTENDED; + } + } + hdr.hdr_signature = htonl(CACHE_SIGNATURE); - hdr.hdr_version = htonl(2); + /* for extended format, increase version so older git won't try to read it */ + hdr.hdr_version = htonl(extended ? 3 : 2); hdr.hdr_entries = htonl(entries - removed); git_SHA1_Init(&c); From e11601381e384898418c30bd537a9daa1210c300 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 18 Nov 2008 21:40:32 +1100 Subject: [PATCH 02/52] gitk: Fix context menu items for generating diffs when in tree mode Currently, if you invoke the "diff this -> selected" or "diff selected -> this" and gitk is in "Tree" mode rather than "Patch" mode, the diff display pane will just show the header but not the actual diff, unless gitk has done the diff before and thus has the list of files that differ. This was because the logic in gettreediffline that checked whether we had moved on to doing something else checked the mode (Tree or Patch) before checking whether the ids we're diffing had changed. This fixes it. The new logic in gettreediffline is slightly hacky and relies on the fact that the Tree/Patch mode only applies when we're looking at a single commit, not at the diff between two commits. Signed-off-by: Paul Mackerras --- gitk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitk b/gitk index f7f177621c..9bdaafe408 100755 --- a/gitk +++ b/gitk @@ -7129,7 +7129,7 @@ proc gettreediffline {gdtf ids} { set treediffs($ids) $treediff } unset treepending - if {$cmitmode eq "tree"} { + if {$cmitmode eq "tree" && [llength $diffids] == 1} { gettree $diffids } elseif {$ids != $diffids} { if {![info exists diffmergeid]} { From 69530cb0c0d5f08dac9bedff56c164b7370f9931 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 28 Nov 2008 18:41:21 -0800 Subject: [PATCH 03/52] builtin-rm.c: explain and clarify the "local change" logic Explain the logic to check local modification a bit more in the comment, especially because the existing comment that talks about "git rm --cached" was placed in a part that was not about "--cached" at all. Also clarify "if .. else if .." structure. Signed-off-by: Junio C Hamano --- builtin-rm.c | 53 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/builtin-rm.c b/builtin-rm.c index b7126e3e25..3d03da09df 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -31,7 +31,8 @@ static void add_list(const char *name) static int check_local_mod(unsigned char *head, int index_only) { - /* items in list are already sorted in the cache order, + /* + * Items in list are already sorted in the cache order, * so we could do this a lot more efficiently by using * tree_desc based traversal if we wanted to, but I am * lazy, and who cares if removal of files is a tad @@ -71,25 +72,55 @@ static int check_local_mod(unsigned char *head, int index_only) */ continue; } + + /* + * "rm" of a path that has changes need to be treated + * carefully not to allow losing local changes + * accidentally. A local change could be (1) file in + * work tree is different since the index; and/or (2) + * the user staged a content that is different from + * the current commit in the index. + * + * In such a case, you would need to --force the + * removal. However, "rm --cached" (remove only from + * the index) is safe if the index matches the file in + * the work tree or the HEAD commit, as it means that + * the content being removed is available elsewhere. + */ + + /* + * Is the index different from the file in the work tree? + */ if (ce_match_stat(ce, &st, 0)) local_changes = 1; + + /* + * Is the index different from the HEAD commit? By + * definition, before the very initial commit, + * anything staged in the index is treated by the same + * way as changed from the HEAD. + */ if (no_head || get_tree_entry(head, name, sha1, &mode) || ce->ce_mode != create_ce_mode(mode) || hashcmp(ce->sha1, sha1)) staged_changes = 1; - if (local_changes && staged_changes && - !(index_only && is_empty_blob_sha1(ce->sha1))) - errs = error("'%s' has staged content different " - "from both the file and the HEAD\n" - "(use -f to force removal)", name); + /* + * If the index does not match the file in the work + * tree and if it does not match the HEAD commit + * either, (1) "git rm" without --cached definitely + * will lose information; (2) "git rm --cached" will + * lose information unless it is about removing an + * "intent to add" entry. + */ + if (local_changes && staged_changes) { + if (!index_only || !is_empty_blob_sha1(ce->sha1)) + errs = error("'%s' has staged content different " + "from both the file and the HEAD\n" + "(use -f to force removal)", name); + } else if (!index_only) { - /* It's not dangerous to "git rm --cached" a - * file if the index matches the file or the - * HEAD, since it means the deleted content is - * still available somewhere. - */ if (staged_changes) errs = error("'%s' has changes staged in the index\n" "(use --cached to keep the file, " From 388b2acd6e649145d4368a10cf4df5f5bbbac2c2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 28 Nov 2008 19:55:25 -0800 Subject: [PATCH 04/52] git add --intent-to-add: fix removal of cached emptiness This uses the extended index flag mechanism introduced earlier to mark the entries added to the index via "git add -N" with CE_INTENT_TO_ADD. The logic to detect an "intent to add" entry for the purpose of allowing "git rm --cached $path" is tightened to check not just for a staged empty blob, but with the CE_INTENT_TO_ADD bit. This protects an empty blob that was explicitly added and then modified in the work tree from being dropped with this sequence: $ >empty $ git add empty $ echo "non empty" >empty $ git rm --cached empty Signed-off-by: Junio C Hamano --- builtin-rm.c | 2 +- cache.h | 3 ++- read-cache.c | 2 ++ t/t3600-rm.sh | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/builtin-rm.c b/builtin-rm.c index 3d03da09df..c11f455858 100644 --- a/builtin-rm.c +++ b/builtin-rm.c @@ -115,7 +115,7 @@ static int check_local_mod(unsigned char *head, int index_only) * "intent to add" entry. */ if (local_changes && staged_changes) { - if (!index_only || !is_empty_blob_sha1(ce->sha1)) + if (!index_only || !(ce->ce_flags & CE_INTENT_TO_ADD)) errs = error("'%s' has staged content different " "from both the file and the HEAD\n" "(use -f to force removal)", name); diff --git a/cache.h b/cache.h index ef2e7f93f7..f15b3fc906 100644 --- a/cache.h +++ b/cache.h @@ -176,10 +176,11 @@ struct cache_entry { /* * Extended on-disk flags */ +#define CE_INTENT_TO_ADD 0x20000000 /* CE_EXTENDED2 is for future extension */ #define CE_EXTENDED2 0x80000000 -#define CE_EXTENDED_FLAGS (0) +#define CE_EXTENDED_FLAGS (CE_INTENT_TO_ADD) /* * Safeguard to avoid saving wrong flags: diff --git a/read-cache.c b/read-cache.c index abc627ba0b..fa30a0f885 100644 --- a/read-cache.c +++ b/read-cache.c @@ -546,6 +546,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st, ce->ce_flags = namelen; if (!intent_only) fill_stat_cache_info(ce, st); + else + ce->ce_flags |= CE_INTENT_TO_ADD; if (trust_executable_bit && has_symlinks) ce->ce_mode = create_ce_mode(st_mode); diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 5b4d6f7138..b7d46e50a8 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -187,8 +187,8 @@ test_expect_success 'but with -f it should work.' ' test_must_fail git ls-files --error-unmatch baz ' -test_expect_failure 'refuse to remove cached empty file with modifications' ' - touch empty && +test_expect_success 'refuse to remove cached empty file with modifications' ' + >empty && git add empty && echo content >empty && test_must_fail git rm --cached empty From 331fcb598ec0127fd89c992361bc573dcd3a4a63 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 28 Nov 2008 19:56:34 -0800 Subject: [PATCH 05/52] git add --intent-to-add: do not let an empty blob be committed by accident Writing a tree out of an index with an "intent to add" entry is blocked. This implies that you cannot "git commit" from such a state; however you can still do "git commit -a" or "git commit $that_path". Signed-off-by: Junio C Hamano --- builtin-commit.c | 2 +- builtin-write-tree.c | 2 +- cache-tree.c | 10 +++++++--- read-cache.c | 8 ++++++++ t/t2203-add-intent.sh | 28 ++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/builtin-commit.c b/builtin-commit.c index 1677e6b45f..2b499fa543 100644 --- a/builtin-commit.c +++ b/builtin-commit.c @@ -639,7 +639,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix) active_cache_tree = cache_tree(); if (cache_tree_update(active_cache_tree, active_cache, active_nr, 0, 0) < 0) { - error("Error building trees; the index is unmerged?"); + error("Error building trees"); return 0; } diff --git a/builtin-write-tree.c b/builtin-write-tree.c index 52a3c015ff..9d640508dd 100644 --- a/builtin-write-tree.c +++ b/builtin-write-tree.c @@ -42,7 +42,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix) die("%s: error reading the index", me); break; case WRITE_TREE_UNMERGED_INDEX: - die("%s: error building trees; the index is unmerged?", me); + die("%s: error building trees", me); break; case WRITE_TREE_PREFIX_ERROR: die("%s: prefix %s not found", me, prefix); diff --git a/cache-tree.c b/cache-tree.c index 5f8ee87bb1..3d8f218a5f 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -155,13 +155,17 @@ static int verify_cache(struct cache_entry **cache, funny = 0; for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; - if (ce_stage(ce)) { + if (ce_stage(ce) || (ce->ce_flags & CE_INTENT_TO_ADD)) { if (10 < ++funny) { fprintf(stderr, "...\n"); break; } - fprintf(stderr, "%s: unmerged (%s)\n", - ce->name, sha1_to_hex(ce->sha1)); + if (ce_stage(ce)) + fprintf(stderr, "%s: unmerged (%s)\n", + ce->name, sha1_to_hex(ce->sha1)); + else + fprintf(stderr, "%s: not added yet\n", + ce->name); } } if (funny) diff --git a/read-cache.c b/read-cache.c index fa30a0f885..8579663ee0 100644 --- a/read-cache.c +++ b/read-cache.c @@ -257,6 +257,14 @@ int ie_match_stat(const struct index_state *istate, if (!ignore_valid && (ce->ce_flags & CE_VALID)) return 0; + /* + * Intent-to-add entries have not been added, so the index entry + * by definition never matches what is in the work tree until it + * actually gets added. + */ + if (ce->ce_flags & CE_INTENT_TO_ADD) + return DATA_CHANGED | TYPE_CHANGED | MODE_CHANGED; + changed = ce_match_stat_basic(ce, st); /* diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index d4de35ea06..58a329961e 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -32,5 +32,33 @@ test_expect_success 'intent to add does not clobber existing paths' ' ! grep "$empty" actual ' +test_expect_success 'cannot commit with i-t-a entry' ' + test_tick && + git commit -a -m initial && + git reset --hard && + + echo xyzzy >rezrov && + echo frotz >nitfol && + git add rezrov && + git add -N nitfol && + test_must_fail git commit +' + +test_expect_success 'can commit with an unrelated i-t-a entry in index' ' + git reset --hard && + echo xyzzy >rezrov && + echo frotz >nitfol && + git add rezrov && + git add -N nitfol && + git commit -m partial rezrov +' + +test_expect_success 'can "commit -a" with an i-t-a entry' ' + git reset --hard && + : >nitfol && + git add -N nitfol && + git commit -a -m all +' + test_done From 8d2dbbac21bbb76af29133331e2a88870d93899d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 29 Nov 2008 12:53:41 -0800 Subject: [PATCH 06/52] gitweb: fix 'ctags' feature check and others gitweb_check_feature() function is to retrieve the configuration parameter list and calling it in the scalar context does not give its first element that tells if the feature is enabled. This fixes all the existing callers to call the function correctly in the list context. Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 933e137386..400f5c8e14 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3914,7 +3914,7 @@ sub fill_project_list_info { my ($projlist, $check_forks) = @_; my @projects; - my $show_ctags = gitweb_check_feature('ctags'); + my ($show_ctags) = gitweb_check_feature('ctags'); PROJECT: foreach my $pr (@$projlist) { my (@activity) = git_get_last_activity($pr->{'path'}); @@ -3988,7 +3988,7 @@ sub git_project_list_body { @projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @projects; } - my $show_ctags = gitweb_check_feature('ctags'); + my ($show_ctags) = gitweb_check_feature('ctags'); if ($show_ctags) { my %ctags; foreach my $p (@projects) { @@ -4457,7 +4457,7 @@ sub git_summary { } # Tag cloud - my $show_ctags = (gitweb_check_feature('ctags'))[0]; + my ($show_ctags) = gitweb_check_feature('ctags'); if ($show_ctags) { my $ctags = git_get_project_ctags($project); my $cloud = git_populate_project_tagcloud($ctags); @@ -4559,7 +4559,7 @@ sub git_blame { my $fd; my $ftype; - gitweb_check_feature('blame') + gitweb_check_feature('blame')[0] or die_error(403, "Blame view not allowed"); die_error(400, "No file name given") unless $file_name; @@ -5610,7 +5610,7 @@ sub git_history { } sub git_search { - gitweb_check_feature('search') or die_error(403, "Search is disabled"); + gitweb_check_feature('search')[0] or die_error(403, "Search is disabled"); if (!defined $searchtext) { die_error(400, "Text field is empty"); } @@ -5629,11 +5629,11 @@ sub git_search { if ($searchtype eq 'pickaxe') { # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature - gitweb_check_feature('pickaxe') + gitweb_check_feature('pickaxe')[0] or die_error(403, "Pickaxe is disabled"); } if ($searchtype eq 'grep') { - gitweb_check_feature('grep') + gitweb_check_feature('grep')[0] or die_error(403, "Grep is disabled"); } From a7c5a283509f6a70753c90393dfad016312b8822 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 29 Nov 2008 13:02:08 -0800 Subject: [PATCH 07/52] gitweb: rename gitweb_check_feature to gitweb_get_feature The function is about retrieving the configuration parameter list for the feature. A more robust way to check if a feature is enabled will be introduced in the next patch, and the function will be called gitweb_check_feature. Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 400f5c8e14..756b24808d 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -190,7 +190,7 @@ our %feature = ( # if there is no 'sub' key (no feature-sub), then feature cannot be # overriden # - # use gitweb_check_feature() to check if is enabled + # # Enable the 'blame' blob view, showing the last commit that modified # each line in the file. This can be very CPU-intensive. @@ -329,7 +329,7 @@ our %feature = ( 'default' => [0]}, ); -sub gitweb_check_feature { +sub gitweb_get_feature { my ($name) = @_; return unless exists $feature{$name}; my ($sub, $override, @defaults) = ( @@ -767,7 +767,7 @@ our $git_dir; $git_dir = "$projectroot/$project" if $project; # list of supported snapshot formats -our @snapshot_fmts = gitweb_check_feature('snapshot'); +our @snapshot_fmts = gitweb_get_feature('snapshot'); @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts); # dispatch @@ -810,7 +810,7 @@ sub href (%) { } } - my ($use_pathinfo) = gitweb_check_feature('pathinfo'); + my ($use_pathinfo) = gitweb_get_feature('pathinfo'); if ($use_pathinfo) { # try to put as many parameters as possible in PATH_INFO: # - project name @@ -2101,7 +2101,7 @@ sub git_get_projects_list { $filter ||= ''; $filter =~ s/\.git$//; - my ($check_forks) = gitweb_check_feature('forks'); + my ($check_forks) = gitweb_get_feature('forks'); if (-d $projects_list) { # search in directory @@ -2947,7 +2947,7 @@ EOF } print "\n"; - my ($have_search) = gitweb_check_feature('search'); + my ($have_search) = gitweb_get_feature('search'); if (defined $project && $have_search) { if (!defined $searchtext) { $searchtext = ""; @@ -2961,7 +2961,7 @@ EOF $search_hash = "HEAD"; } my $action = $my_uri; - my ($use_pathinfo) = gitweb_check_feature('pathinfo'); + my ($use_pathinfo) = gitweb_get_feature('pathinfo'); if ($use_pathinfo) { $action .= "/".esc_url($project); } @@ -3084,7 +3084,7 @@ sub git_print_page_nav { $arg{'tree'}{'hash'} = $treehead if defined $treehead; $arg{'tree'}{'hash_base'} = $treebase if defined $treebase; - my @actions = gitweb_check_feature('actions'); + my @actions = gitweb_get_feature('actions'); my %repl = ( '%' => '%', 'n' => $project, # project name @@ -3454,7 +3454,7 @@ sub is_patch_split { sub git_difftree_body { my ($difftree, $hash, @parents) = @_; my ($parent) = $parents[0]; - my ($have_blame) = gitweb_check_feature('blame'); + my ($have_blame) = gitweb_get_feature('blame'); print "
\n"; if ($#{$difftree} > 10) { print(($#{$difftree} + 1) . " files changed:\n"); @@ -3914,7 +3914,7 @@ sub fill_project_list_info { my ($projlist, $check_forks) = @_; my @projects; - my ($show_ctags) = gitweb_check_feature('ctags'); + my ($show_ctags) = gitweb_get_feature('ctags'); PROJECT: foreach my $pr (@$projlist) { my (@activity) = git_get_last_activity($pr->{'path'}); @@ -3968,7 +3968,7 @@ sub git_project_list_body { # actually uses global variable $project my ($projlist, $order, $from, $to, $extra, $no_header) = @_; - my ($check_forks) = gitweb_check_feature('forks'); + my ($check_forks) = gitweb_get_feature('forks'); my @projects = fill_project_list_info($projlist, $check_forks); $order ||= $default_projects_order; @@ -3988,7 +3988,7 @@ sub git_project_list_body { @projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @projects; } - my ($show_ctags) = gitweb_check_feature('ctags'); + my ($show_ctags) = gitweb_get_feature('ctags'); if ($show_ctags) { my %ctags; foreach my $p (@projects) { @@ -4428,7 +4428,7 @@ sub git_summary { my @taglist = git_get_tags_list(16); my @headlist = git_get_heads_list(16); my @forklist; - my ($check_forks) = gitweb_check_feature('forks'); + my ($check_forks) = gitweb_get_feature('forks'); if ($check_forks) { @forklist = git_get_projects_list($project); @@ -4457,7 +4457,7 @@ sub git_summary { } # Tag cloud - my ($show_ctags) = gitweb_check_feature('ctags'); + my ($show_ctags) = gitweb_get_feature('ctags'); if ($show_ctags) { my $ctags = git_get_project_ctags($project); my $cloud = git_populate_project_tagcloud($ctags); @@ -4559,7 +4559,7 @@ sub git_blame { my $fd; my $ftype; - gitweb_check_feature('blame')[0] + gitweb_get_feature('blame')[0] or die_error(403, "Blame view not allowed"); die_error(400, "No file name given") unless $file_name; @@ -4747,7 +4747,7 @@ sub git_blob { $expires = "+1d"; } - my ($have_blame) = gitweb_check_feature('blame'); + my ($have_blame) = gitweb_get_feature('blame'); open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash or die_error(500, "Couldn't cat $file_name, $hash"); my $mimetype = blob_mimetype($fd, $file_name); @@ -4840,7 +4840,7 @@ sub git_tree { my $ref = format_ref_marker($refs, $hash_base); git_header_html(); my $basedir = ''; - my ($have_blame) = gitweb_check_feature('blame'); + my ($have_blame) = gitweb_get_feature('blame'); if (defined $hash_base && (my %co = parse_commit($hash_base))) { my @views_nav = (); if (defined $file_name) { @@ -5610,7 +5610,7 @@ sub git_history { } sub git_search { - gitweb_check_feature('search')[0] or die_error(403, "Search is disabled"); + gitweb_get_feature('search')[0] or die_error(403, "Search is disabled"); if (!defined $searchtext) { die_error(400, "Text field is empty"); } @@ -5629,11 +5629,11 @@ sub git_search { if ($searchtype eq 'pickaxe') { # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature - gitweb_check_feature('pickaxe')[0] + gitweb_get_feature('pickaxe')[0] or die_error(403, "Pickaxe is disabled"); } if ($searchtype eq 'grep') { - gitweb_check_feature('grep')[0] + gitweb_get_feature('grep')[0] or die_error(403, "Grep is disabled"); } @@ -5838,7 +5838,7 @@ insensitive).

commit
The commit messages and authorship information will be scanned for the given pattern.
EOT - my ($have_grep) = gitweb_check_feature('grep'); + my ($have_grep) = gitweb_get_feature('grep'); if ($have_grep) { print <grep @@ -5855,7 +5855,7 @@ EOT
committer
Name and e-mail of the committer and date of commit will be scanned for the given pattern.
EOT - my ($have_pickaxe) = gitweb_check_feature('pickaxe'); + my ($have_pickaxe) = gitweb_get_feature('pickaxe'); if ($have_pickaxe) { print <pickaxe @@ -5907,7 +5907,7 @@ sub git_shortlog { sub git_feed { my $format = shift || 'atom'; - my ($have_blame) = gitweb_check_feature('blame'); + my ($have_blame) = gitweb_get_feature('blame'); # Atom: http://www.atomenabled.org/developers/syndication/ # RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ From 25b2790fff5b7b484f1a2f40fafa4b24db1506a2 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Sat, 29 Nov 2008 13:07:29 -0800 Subject: [PATCH 08/52] gitweb: make gitweb_check_feature a boolean wrapper The gitweb_get_feature() function retrieves the configuration parameters for the feature (such as the list of snapshot formats or the list of additional actions), but it is very often used to see if feature is enabled (which is returned as the first element in the list). Because accepting the returned list in the scalar context by mistake yields the number of elements in the array, which is non-zero in all cases, such a mistake would result in a bug for the latter use, with disabled features appearing enabled. All existing callers that call the function for this purpose assign the return value in the list context to retrieve the first element, but that is only because we fixed careless callers recently. This adds gitweb_check_feature() as a wrapper to gitweb_get_feature() that can be called safely in the scalar context to see if a feature is enabled to reduce the risk of future bugs. Callers of "get" that use the call only to see if the feature is enabled are updated to call this wrapper. Signed-off-by: Giuseppe Bilotta Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 756b24808d..acc4cfdcda 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -190,7 +190,7 @@ our %feature = ( # if there is no 'sub' key (no feature-sub), then feature cannot be # overriden # - # + # use gitweb_check_feature() to check if is enabled # Enable the 'blame' blob view, showing the last commit that modified # each line in the file. This can be very CPU-intensive. @@ -344,6 +344,22 @@ sub gitweb_get_feature { return $sub->(@defaults); } +# A wrapper to check if a given feature is enabled. +# With this, you can say +# +# my $bool_feat = gitweb_check_feature('bool_feat'); +# gitweb_check_feature('bool_feat') or somecode; +# +# instead of +# +# my ($bool_feat) = gitweb_get_feature('bool_feat'); +# (gitweb_get_feature('bool_feat'))[0] or somecode; +# +sub gitweb_check_feature { + return (gitweb_get_feature(@_))[0]; +} + + sub feature_blame { my ($val) = git_get_project_config('blame', '--bool'); @@ -810,7 +826,7 @@ sub href (%) { } } - my ($use_pathinfo) = gitweb_get_feature('pathinfo'); + my $use_pathinfo = gitweb_check_feature('pathinfo'); if ($use_pathinfo) { # try to put as many parameters as possible in PATH_INFO: # - project name @@ -2101,7 +2117,7 @@ sub git_get_projects_list { $filter ||= ''; $filter =~ s/\.git$//; - my ($check_forks) = gitweb_get_feature('forks'); + my $check_forks = gitweb_check_feature('forks'); if (-d $projects_list) { # search in directory @@ -2947,7 +2963,7 @@ EOF } print "
\n"; - my ($have_search) = gitweb_get_feature('search'); + my $have_search = gitweb_check_feature('search'); if (defined $project && $have_search) { if (!defined $searchtext) { $searchtext = ""; @@ -2961,7 +2977,7 @@ EOF $search_hash = "HEAD"; } my $action = $my_uri; - my ($use_pathinfo) = gitweb_get_feature('pathinfo'); + my $use_pathinfo = gitweb_check_feature('pathinfo'); if ($use_pathinfo) { $action .= "/".esc_url($project); } @@ -3454,7 +3470,7 @@ sub is_patch_split { sub git_difftree_body { my ($difftree, $hash, @parents) = @_; my ($parent) = $parents[0]; - my ($have_blame) = gitweb_get_feature('blame'); + my $have_blame = gitweb_check_feature('blame'); print "
\n"; if ($#{$difftree} > 10) { print(($#{$difftree} + 1) . " files changed:\n"); @@ -3914,7 +3930,7 @@ sub fill_project_list_info { my ($projlist, $check_forks) = @_; my @projects; - my ($show_ctags) = gitweb_get_feature('ctags'); + my $show_ctags = gitweb_check_feature('ctags'); PROJECT: foreach my $pr (@$projlist) { my (@activity) = git_get_last_activity($pr->{'path'}); @@ -3968,7 +3984,7 @@ sub git_project_list_body { # actually uses global variable $project my ($projlist, $order, $from, $to, $extra, $no_header) = @_; - my ($check_forks) = gitweb_get_feature('forks'); + my $check_forks = gitweb_check_feature('forks'); my @projects = fill_project_list_info($projlist, $check_forks); $order ||= $default_projects_order; @@ -3988,7 +4004,7 @@ sub git_project_list_body { @projects = sort {$a->{$oi->{'key'}} <=> $b->{$oi->{'key'}}} @projects; } - my ($show_ctags) = gitweb_get_feature('ctags'); + my $show_ctags = gitweb_check_feature('ctags'); if ($show_ctags) { my %ctags; foreach my $p (@projects) { @@ -4428,7 +4444,7 @@ sub git_summary { my @taglist = git_get_tags_list(16); my @headlist = git_get_heads_list(16); my @forklist; - my ($check_forks) = gitweb_get_feature('forks'); + my $check_forks = gitweb_check_feature('forks'); if ($check_forks) { @forklist = git_get_projects_list($project); @@ -4457,7 +4473,7 @@ sub git_summary { } # Tag cloud - my ($show_ctags) = gitweb_get_feature('ctags'); + my $show_ctags = gitweb_check_feature('ctags'); if ($show_ctags) { my $ctags = git_get_project_ctags($project); my $cloud = git_populate_project_tagcloud($ctags); @@ -4559,7 +4575,7 @@ sub git_blame { my $fd; my $ftype; - gitweb_get_feature('blame')[0] + gitweb_check_feature('blame') or die_error(403, "Blame view not allowed"); die_error(400, "No file name given") unless $file_name; @@ -4747,7 +4763,7 @@ sub git_blob { $expires = "+1d"; } - my ($have_blame) = gitweb_get_feature('blame'); + my $have_blame = gitweb_check_feature('blame'); open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash or die_error(500, "Couldn't cat $file_name, $hash"); my $mimetype = blob_mimetype($fd, $file_name); @@ -4840,7 +4856,7 @@ sub git_tree { my $ref = format_ref_marker($refs, $hash_base); git_header_html(); my $basedir = ''; - my ($have_blame) = gitweb_get_feature('blame'); + my $have_blame = gitweb_check_feature('blame'); if (defined $hash_base && (my %co = parse_commit($hash_base))) { my @views_nav = (); if (defined $file_name) { @@ -5610,7 +5626,7 @@ sub git_history { } sub git_search { - gitweb_get_feature('search')[0] or die_error(403, "Search is disabled"); + gitweb_check_feature('search') or die_error(403, "Search is disabled"); if (!defined $searchtext) { die_error(400, "Text field is empty"); } @@ -5629,11 +5645,11 @@ sub git_search { if ($searchtype eq 'pickaxe') { # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature - gitweb_get_feature('pickaxe')[0] + gitweb_check_feature('pickaxe') or die_error(403, "Pickaxe is disabled"); } if ($searchtype eq 'grep') { - gitweb_get_feature('grep')[0] + gitweb_check_feature('grep') or die_error(403, "Grep is disabled"); } @@ -5838,7 +5854,7 @@ insensitive).

commit
The commit messages and authorship information will be scanned for the given pattern.
EOT - my ($have_grep) = gitweb_get_feature('grep'); + my $have_grep = gitweb_check_feature('grep'); if ($have_grep) { print <grep @@ -5855,7 +5871,7 @@ EOT
committer
Name and e-mail of the committer and date of commit will be scanned for the given pattern.
EOT - my ($have_pickaxe) = gitweb_get_feature('pickaxe'); + my $have_pickaxe = gitweb_check_feature('pickaxe'); if ($have_pickaxe) { print <pickaxe @@ -5907,7 +5923,7 @@ sub git_shortlog { sub git_feed { my $format = shift || 'atom'; - my ($have_blame) = gitweb_get_feature('blame'); + my $have_blame = gitweb_check_feature('blame'); # Atom: http://www.atomenabled.org/developers/syndication/ # RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ From 8b39e04f39c287d8c66b24cc4f6c72916831455c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 2 Dec 2008 09:02:46 +1100 Subject: [PATCH 09/52] gitk: Highlight only when search type is "containing:". When the search type is "touching paths" or "adding/removing string", it's not very useful to highlight instances of the search string in the commit message, headline or author name, so this disables the highlighting in those cases. This was suggested by Mark Burton , but the implementation is different to his patch, which tested $gdttype at each place where $markingmatches was tested. Signed-off-by: Paul Mackerras --- gitk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gitk b/gitk index 9bdaafe408..52d8aaef89 100755 --- a/gitk +++ b/gitk @@ -4121,7 +4121,7 @@ proc askvhighlight {row id} { proc hfiles_change {} { global highlight_files filehighlight fhighlights fh_serial - global highlight_paths gdttype + global highlight_paths if {[info exists filehighlight]} { # delete previous highlights @@ -6286,10 +6286,11 @@ proc findmore {} { proc findselectline {l} { global findloc commentend ctext findcurline markingmatches gdttype - set markingmatches 1 + set markingmatches [expr {$gdttype eq [mc "containing:"]}] set findcurline $l selectline $l 1 - if {$findloc == [mc "All fields"] || $findloc == [mc "Comments"]} { + if {$markingmatches && + ($findloc eq [mc "All fields"] || $findloc eq [mc "Comments"])} { # highlight the matches in the comments set f [$ctext get 1.0 $commentend] set matches [findmatches $f] From 6e7e87c762fb0d8aa21c96c1d2c4596e46f2ab7b Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 2 Dec 2008 09:17:46 +1100 Subject: [PATCH 10/52] gitk: Fix bug in accessing undefined "notflag" variable As pointed out by Johannes Sixt and Alexander Gavrilov, commit 2958228430b63f2e38c55519d1f98d8d6d9e23f3 ("gitk: Fix switch statement in parseviewargs") exposed a latent bug in that $notflag was never initialized. Since it isn't used either, this removes it entirely. Signed-off-by: Paul Mackerras --- gitk | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/gitk b/gitk index 52d8aaef89..b7447f91c0 100755 --- a/gitk +++ b/gitk @@ -199,11 +199,7 @@ proc parseviewargs {n arglist} { set nextisval 1 lappend glflags $arg } - "--not" { - set notflag [expr {!$notflag}] - lappend revargs $arg - } - "--all" { + "--not" - "--all" { lappend revargs $arg } "--merge" { From a8833ef5404a07983d8eed0a9582c2e19e437b78 Mon Sep 17 00:00:00 2001 From: Christian Stimming Date: Sat, 25 Oct 2008 13:25:35 +0200 Subject: [PATCH 11/52] gitk: Update German translation This takes into account the most recent po file merge. Signed-off-by: Christian Stimming Signed-off-by: Paul Mackerras --- po/de.po | 51 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/po/de.po b/po/de.po index c86cc2df5e..e0a6deeded 100644 --- a/po/de.po +++ b/po/de.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-10-18 22:03+1100\n" -"PO-Revision-Date: 2008-05-24 22:40+0200\n" +"POT-Creation-Date: 2008-10-25 13:18+0200\n" +"PO-Revision-Date: 2008-10-25 13:23+0200\n" "Last-Translator: Christian Stimming \n" "Language-Team: German\n" "MIME-Version: 1.0\n" @@ -19,6 +19,14 @@ msgstr "" msgid "Couldn't get list of unmerged files:" msgstr "Liste der nicht-zusammengeführten Dateien nicht gefunden:" +#: gitk:272 +msgid "Error parsing revisions:" +msgstr "Fehler beim Laden der Versionen:" + +#: gitk:327 +msgid "Error executing --argscmd command:" +msgstr "Fehler beim --argscmd Kommando:" + #: gitk:340 msgid "No files selected: --merge specified but no files are unmerged." msgstr "" @@ -283,9 +291,9 @@ msgstr "Nur diesen hervorheben" msgid "External diff" msgstr "Externer Vergleich" -#: gitk:2245 +#: gitk:2255 msgid "Blame parent commit" -msgstr "" +msgstr "Annotieren der Elternversion" #: gitk:2488 msgid "" @@ -471,7 +479,33 @@ msgstr "<%s-Minus>\tSchriftgröße verkleinern" msgid "\t\tUpdate" msgstr "\t\tAktualisieren" -#: gitk:3200 +#: gitk:2979 +#, tcl-format +msgid "Error getting \"%s\" from %s:" +msgstr "Fehler beim Holen von »%s« von »%s«:" + +#: gitk:3036 gitk:3045 +#, tcl-format +msgid "Error creating temporary directory %s:" +msgstr "Fehler beim Erzeugen eines temporären Verzeichnisses »%s«:" + +#: gitk:3058 +msgid "command failed:" +msgstr "Kommando fehlgeschlagen:" + +#: gitk:3078 +msgid "No such commit" +msgstr "Version nicht gefunden" + +#: gitk:3083 +msgid "git gui blame: command failed:" +msgstr "git gui blame: Kommando fehlgeschlagen:" + +#: gitk:3092 +msgid "External diff viewer failed:" +msgstr "Externes Vergleich-(Diff-)Programm fehlgeschlagen:" + +#: gitk:3210 msgid "Gitk view definition" msgstr "Gitk Ansichten" @@ -692,9 +726,10 @@ msgstr "Bitte geben Sie einen Namen für den neuen Zweig an." #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" -"Version »%s« ist bereits im Zweig »%s« enthalten -- trotzdem erneut eintragen?" +"Version »%s« ist bereits im Zweig »%s« enthalten -- trotzdem erneut " +"eintragen?" -#: gitk:7708 +#: gitk:7718 msgid "Cherry-picking" msgstr "Version pflücken" @@ -836,7 +871,7 @@ msgstr "Vergleich nur für angezeigte Pfade" #: gitk:9414 msgid "Support per-file encodings" -msgstr "" +msgstr "Zeichenkodierung pro Datei ermitteln" #: gitk:9421 msgid "External diff tool" From f3413079d6a0d3d3cbeb506e81e647772b857f81 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Mon, 1 Dec 2008 20:30:09 +0300 Subject: [PATCH 12/52] gitk: Make line origin search update the busy status Currently the 'show origin of this line' feature does not update the status field of the gitk window, so it is not evident that any processing is going on. It may seem at first that clicking the item had no effect. This commit adds calls to set and clear the busy status with an appropriate title, similar to other search commands. Signed-off-by: Alexander Gavrilov Signed-off-by: Paul Mackerras --- gitk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gitk b/gitk index b7447f91c0..b8b5e80927 100755 --- a/gitk +++ b/gitk @@ -3402,6 +3402,7 @@ proc show_line_source {} { error_popup [mc "Couldn't start git blame: %s" $err] return } + nowbusy blaming [mc "Searching"] fconfigure $f -blocking 0 set i [reg_instance $f] set blamestuff($i) {} @@ -3415,6 +3416,7 @@ proc stopblaming {} { if {[info exists blameinst]} { stop_instance $blameinst unset blameinst + notbusy blaming } } @@ -3429,6 +3431,7 @@ proc read_line_source {fd inst} { } unset commfd($inst) unset blameinst + notbusy blaming fconfigure $fd -blocking 1 if {[catch {close $fd} err]} { error_popup [mc "Error running git blame: %s" $err] From 7fb0abb19563d36d8e210198b6c2debbf3362812 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 13 Nov 2008 23:12:42 +0300 Subject: [PATCH 13/52] gitk: Add a menu option to start git gui Git gui already has menu commands to start gitk, and this makes the relation symmetric. [paulus@samba.org - changed "Git Gui" in the menu item to "git gui"] Signed-off-by: Alexander Gavrilov Signed-off-by: Paul Mackerras --- gitk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gitk b/gitk index b8b5e80927..64a873d2ef 100755 --- a/gitk +++ b/gitk @@ -1911,6 +1911,9 @@ proc makewindow {} { {mc "Reload" command reloadcommits -accelerator Meta1-F5} {mc "Reread references" command rereadrefs} {mc "List references" command showrefs -accelerator F2} + {xx "" separator} + {mc "Start git gui" command {exec git gui &}} + {xx "" separator} {mc "Quit" command doquit -accelerator Meta1-Q} }} {mc "Edit" cascade { From 861c68e3b6a8d10af5517e6750a66407d32105aa Mon Sep 17 00:00:00 2001 From: Mark Burton Date: Tue, 2 Dec 2008 15:15:02 +0000 Subject: [PATCH 14/52] git-gui: Teach start_push_anywhere_action{} to notice when remote is a mirror. When the destination repository is a mirror, this function goofed by still passing a refspec to git-push. Now it notices that the remote is a mirror and holds the refspec. Signed-off-by: Mark Burton Signed-off-by: Shawn O. Pearce --- lib/transport.tcl | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/transport.tcl b/lib/transport.tcl index e419d7810a..b18d9c7a1b 100644 --- a/lib/transport.tcl +++ b/lib/transport.tcl @@ -33,10 +33,15 @@ proc push_to {remote} { proc start_push_anywhere_action {w} { global push_urltype push_remote push_url push_thin push_tags global push_force + global repo_config + set is_mirror 0 set r_url {} switch -- $push_urltype { - remote {set r_url $push_remote} + remote { + set r_url $push_remote + catch {set is_mirror $repo_config(remote.$push_remote.mirror)} + } url {set r_url $push_url} } if {$r_url eq {}} return @@ -53,23 +58,29 @@ proc start_push_anywhere_action {w} { lappend cmd --tags } lappend cmd $r_url - set cnt 0 - foreach i [$w.source.l curselection] { - set b [$w.source.l get $i] - lappend cmd "refs/heads/$b:refs/heads/$b" - incr cnt - } - if {$cnt == 0} { - return - } elseif {$cnt == 1} { - set unit branch + if {$is_mirror} { + set cons [console::new \ + [mc "push %s" $r_url] \ + [mc "Mirroring to %s" $r_url]] } else { - set unit branches - } + set cnt 0 + foreach i [$w.source.l curselection] { + set b [$w.source.l get $i] + lappend cmd "refs/heads/$b:refs/heads/$b" + incr cnt + } + if {$cnt == 0} { + return + } elseif {$cnt == 1} { + set unit branch + } else { + set unit branches + } - set cons [console::new \ - [mc "push %s" $r_url] \ - [mc "Pushing %s %s to %s" $cnt $unit $r_url]] + set cons [console::new \ + [mc "push %s" $r_url] \ + [mc "Pushing %s %s to %s" $cnt $unit $r_url]] + } console::exec $cons $cmd destroy $w } From 25e30fa08e687d584d9dd87d13acf84bb1e1858c Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Mon, 1 Dec 2008 19:50:02 +0100 Subject: [PATCH 15/52] User's Manual: remove duplicated url at the end of Appendix B Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- Documentation/user-manual.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 39c0167e1e..b6533fa206 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -4560,4 +4560,3 @@ Alternates, clone -reference, etc. More on recovery from repository corruption. See: http://marc.theaimsgroup.com/?l=git&m=117263864820799&w=2 http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2 - http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2 From ff3c0ff20e2c0b2c78d2c2da9ce4eb0739ff6ced Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Tue, 2 Dec 2008 14:57:28 -0800 Subject: [PATCH 16/52] Update comment on gitweb_check/get_feature This is taken from a patch from Giuseppe but unfortunately it came too late to replace the series that was already on "next". The comment he updated here is better than the version we had previously, so I am cherry-picking this bit not to lose it. Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index acc4cfdcda..2738643950 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -190,7 +190,9 @@ our %feature = ( # if there is no 'sub' key (no feature-sub), then feature cannot be # overriden # - # use gitweb_check_feature() to check if is enabled + # use gitweb_get_feature() to retrieve the value + # (an array) or gitweb_check_feature() to check if + # is enabled # Enable the 'blame' blob view, showing the last commit that modified # each line in the file. This can be very CPU-intensive. From 1a66a489d09e7b8629fa7e4184c78703f4eed335 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Tue, 2 Dec 2008 14:53:47 +0100 Subject: [PATCH 17/52] bisect: fix "git bisect skip " and add tests cases The patch that allows "git bisect skip" to be passed a range of commits using the ".." notation is flawed because it introduces a regression when it was passed a simple rev or commit. "git bisect skip " doesn't work any more, because is quoted but not properly unquoted. This patch fixes that and add tests cases to better check when it is passed commits and range of commits. While at it, this patch also properly quotes the non range arguments using the "sq" function. Signed-off-by: Christian Couder --- git-bisect.sh | 4 ++-- t/t6030-bisect-porcelain.sh | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/git-bisect.sh b/git-bisect.sh index 6706bc1e7c..ddbdba8af1 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -199,11 +199,11 @@ bisect_skip() { *..*) revs=$(git rev-list "$arg") || die "Bad rev input: $arg" ;; *) - revs="'$arg'" ;; + revs=$(sq "$arg") ;; esac all="$all $revs" done - bisect_state 'skip' $all + eval bisect_state 'skip' $all } bisect_state() { diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 85fa39cf0b..dd7eac84ea 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -313,8 +313,25 @@ test_expect_success 'bisect run & skip: find first bad' ' grep "$HASH6 is first bad commit" my_bisect_log.txt ' -test_expect_success 'bisect starting with a detached HEAD' ' +test_expect_success 'bisect skip only one range' ' + git bisect reset && + git bisect start $HASH7 $HASH1 && + git bisect skip $HASH1..$HASH5 && + test "$HASH6" = "$(git rev-parse --verify HEAD)" && + test_must_fail git bisect bad > my_bisect_log.txt && + grep "first bad commit could be any of" my_bisect_log.txt +' +test_expect_success 'bisect skip many ranges' ' + git bisect start $HASH7 $HASH1 && + test "$HASH4" = "$(git rev-parse --verify HEAD)" && + git bisect skip $HASH2 $HASH2.. ..$HASH5 && + test "$HASH6" = "$(git rev-parse --verify HEAD)" && + test_must_fail git bisect bad > my_bisect_log.txt && + grep "first bad commit could be any of" my_bisect_log.txt +' + +test_expect_success 'bisect starting with a detached HEAD' ' git bisect reset && git checkout master^ && HEAD=$(git rev-parse --verify HEAD) && From 5413812f0800e5530036671ee55476f2771ab828 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Tue, 2 Dec 2008 14:53:51 +0100 Subject: [PATCH 18/52] Documentation: describe how to "bisect skip" a range of commits Signed-off-by: Christian Couder --- Documentation/git-bisect.txt | 21 ++++++++++++++++++++- git-bisect.sh | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 39034ec7d6..147ea38197 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -19,7 +19,7 @@ on the subcommand: git bisect start [ [...]] [--] [...] git bisect bad [] git bisect good [...] - git bisect skip [...] + git bisect skip [(|)...] git bisect reset [] git bisect visualize git bisect replay @@ -164,6 +164,25 @@ But computing the commit to test may be slower afterwards and git may eventually not be able to tell the first bad among a bad and one or more "skip"ped commits. +You can even skip a range of commits, instead of just one commit, +using the "''..''" notation. For example: + +------------ +$ git bisect skip v2.5..v2.6 +------------ + +would mean that no commit between `v2.5` excluded and `v2.6` included +can be tested. + +Note that if you want to also skip the first commit of a range you can +use something like: + +------------ +$ git bisect skip v2.5 v2.5..v2.6 +------------ + +and the commit pointed to by `v2.5` will be skipped too. + Cutting down bisection by giving more parameters to bisect start ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/git-bisect.sh b/git-bisect.sh index ddbdba8af1..17a35f6adc 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -9,7 +9,7 @@ git bisect bad [] mark a known-bad revision. git bisect good [...] mark ... known-good revisions. -git bisect skip [...] +git bisect skip [(|)...] mark ... untestable revisions. git bisect next find next bisection to test and check it out. From 46059cc63259f7a3d408fc1e52e8da9d37dc49ff Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 15 Nov 2008 04:08:14 -0800 Subject: [PATCH 19/52] Makefile: introduce NO_PTHREADS This introduces make variable NO_PTHREADS for platforms that lack the support for pthreads library or people who do not want to use it for whatever reason. When defined, it makes the multi-threaded index preloading into a no-op, and also disables threaded delta searching by pack-objects. Signed-off-by: Junio C Hamano Signed-off-by: Mike Ralphson Tested-by: Johannes Sixt (AIX 4.3.x) Signed-off-by: Junio C Hamano --- Makefile | 17 ++++++++++++++++- config.mak.in | 1 + configure.ac | 5 +++++ preload-index.c | 9 +++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 649cfb819f..9577d6fc73 100644 --- a/Makefile +++ b/Makefile @@ -90,6 +90,8 @@ all:: # # Define NO_MMAP if you want to avoid mmap. # +# Define NO_PTHREADS if you do not have or do not want to use Pthreads. +# # Define NO_PREAD if you have a problem with pread() system call (e.g. # cygwin.dll before v1.5.22). # @@ -164,6 +166,7 @@ uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not') uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') +uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') # CFLAGS and LDFLAGS are for the users to override from the command line. @@ -722,6 +725,11 @@ ifeq ($(uname_S),AIX) INTERNAL_QSORT = UnfortunatelyYes NEEDS_LIBICONV=YesPlease BASIC_CFLAGS += -D_LARGE_FILES + ifneq ($(shell expr "$(uname_V)" : '[1234]'),1) + THREADED_DELTA_SEARCH = YesPlease + else + NO_PTHREADS = YesPlease + endif endif ifeq ($(uname_S),GNU) # GNU/Hurd @@ -766,6 +774,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_STRCASESTR = YesPlease NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease + NO_PTHREADS = YesPlease NEEDS_LIBICONV = YesPlease OLD_ICONV = YesPlease NO_C99_FORMAT = YesPlease @@ -1017,9 +1026,15 @@ ifdef INTERNAL_QSORT COMPAT_OBJS += compat/qsort.o endif +ifdef NO_PTHREADS + THREADED_DELTA_SEARCH = + BASIC_CFLAGS += -DNO_PTHREADS +else + EXTLIBS += $(PTHREAD_LIBS) +endif + ifdef THREADED_DELTA_SEARCH BASIC_CFLAGS += -DTHREADED_DELTA_SEARCH - EXTLIBS += $(PTHREAD_LIBS) LIB_OBJS += thread-utils.o endif ifdef DIR_HAS_BSD_GROUP_SEMANTICS diff --git a/config.mak.in b/config.mak.in index ea7705c1ed..14dfb21fa5 100644 --- a/config.mak.in +++ b/config.mak.in @@ -51,4 +51,5 @@ OLD_ICONV=@OLD_ICONV@ NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@ FREAD_READS_DIRECTORIES=@FREAD_READS_DIRECTORIES@ SNPRINTF_RETURNS_BOGUS=@SNPRINTF_RETURNS_BOGUS@ +NO_PTHREADS=@NO_PTHREADS@ PTHREAD_LIBS=@PTHREAD_LIBS@ diff --git a/configure.ac b/configure.ac index 42567420e0..8821b5080a 100644 --- a/configure.ac +++ b/configure.ac @@ -490,6 +490,8 @@ AC_SUBST(NO_MKDTEMP) # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. # Enable it on Windows. By default, symrefs are still used. # +# Define NO_PTHREADS if we do not have pthreads +# # Define PTHREAD_LIBS to the linker flag used for Pthread support. AC_LANG_CONFTEST([AC_LANG_PROGRAM( [[#include ]], @@ -502,9 +504,12 @@ else ${CC} -lpthread conftest.c -o conftest.o > /dev/null 2>&1 if test $? -eq 0;then PTHREAD_LIBS="-lpthread" + else + NO_PTHREADS=UnfortunatelyYes fi fi AC_SUBST(PTHREAD_LIBS) +AC_SUBST(NO_PTHREADS) ## Site configuration (override autodetection) ## --with-PACKAGE[=ARG] and --without-PACKAGE diff --git a/preload-index.c b/preload-index.c index a6855837a4..88edc5f8a9 100644 --- a/preload-index.c +++ b/preload-index.c @@ -2,6 +2,14 @@ * Copyright (C) 2008 Linus Torvalds */ #include "cache.h" + +#ifdef NO_PTHREADS +static void preload_index(struct index_state *index, const char **pathspec) +{ + ; /* nothing */ +} +#else + #include /* @@ -81,6 +89,7 @@ static void preload_index(struct index_state *index, const char **pathspec) die("unable to join threaded lstat"); } } +#endif int read_index_preload(struct index_state *index, const char **pathspec) { From d404bf0288ac1a2c4276d009c0e1c88519e5a7c9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 1 Dec 2008 08:41:50 -0800 Subject: [PATCH 20/52] Add backslash to list of 'crud' characters in real name We remove crud characters at the beginning and end of real-names so that when we see email addresses like From: "David S. Miller" we drop the quotes around the name when we parse that and split it up into name and email. However, the list of crud characters was basically just a random list of common things that are found around names, and it didn't contain the backslash character that some insane scripts seem to use when quoting things. So now the kernel has a number of authors listed like Author: \"Rafael J. Wysocki\ because the author name had started out as From: \"Rafael J. Wysocki\" and the only "crud" character we noticed and removed was the final double-quote at the end. We should probably do better quote removal from names anyway, but this is the minimal obvious patch. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- ident.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ident.c b/ident.c index 09cf0c95c9..99f1c85ea5 100644 --- a/ident.c +++ b/ident.c @@ -121,6 +121,7 @@ static int crud(unsigned char c) c == '<' || c == '>' || c == '"' || + c == '\\' || c == '\''; } From 11920d28da1ac1b65eb4041c1b7355924e5d1366 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Mon, 1 Dec 2008 22:14:55 -0800 Subject: [PATCH 21/52] Add a built-in alias for 'stage' to the 'add' command This comes from conversation at the GitTogether where we thought it would be helpful to be able to teach people to 'stage' files because it tends to cause confusion when told that they have to keep 'add'ing them. This continues the movement to start referring to the index as a staging area (eg: the --staged alias to 'git diff'). Also adds a doc file for 'git stage' that basically points to the docs for 'git add'. Signed-off-by: Scott Chacon Signed-off-by: Junio C Hamano --- Documentation/git-stage.txt | 19 +++++++++++++++++++ git.c | 1 + 2 files changed, 20 insertions(+) create mode 100644 Documentation/git-stage.txt diff --git a/Documentation/git-stage.txt b/Documentation/git-stage.txt new file mode 100644 index 0000000000..7f251a5865 --- /dev/null +++ b/Documentation/git-stage.txt @@ -0,0 +1,19 @@ +git-stage(1) +============== + +NAME +---- +git-stage - Add file contents to the staging area + + +SYNOPSIS +-------- +[verse] +'git stage' args... + + +DESCRIPTION +----------- + +This is a synonym for linkgit:git-add[1]. Please refer to the +documentation of that command. diff --git a/git.c b/git.c index 89feb0b6dc..9e5813cc92 100644 --- a/git.c +++ b/git.c @@ -266,6 +266,7 @@ static void handle_internal_command(int argc, const char **argv) const char *cmd = argv[0]; static struct cmd_struct commands[] = { { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE }, + { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE }, { "annotate", cmd_annotate, RUN_SETUP }, { "apply", cmd_apply }, { "archive", cmd_archive }, From deb13872becbc5fb49e3ab22dd9feaf4e429a853 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Tue, 2 Dec 2008 09:31:01 +0100 Subject: [PATCH 22/52] t4030-diff-textconv: Make octal escape sequence more portable There are printfs around that do not grok '\1', but need '\01'. Discovered on AIX 4.3.x. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t4030-diff-textconv.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index 0b76e7c97a..2f27a0ba9e 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -29,7 +29,7 @@ test_expect_success 'setup binary file with history' ' printf "\\0\\n" >file && git add file && git commit -m one && - printf "\\1\\n" >>file && + printf "\\01\\n" >>file && git add file && git commit -m two ' From 757c7f60a78004fc3d0ea62f44320d54ef430c10 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 2 Dec 2008 01:56:09 +0100 Subject: [PATCH 23/52] git-stash: use git rev-parse -q Don't redirect stderr to /dev/null, use -q to suppress the output on stderr. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-stash.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index b9ace99704..c0532e8751 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -30,7 +30,7 @@ clear_stash () { then die "git stash clear with parameters is unimplemented" fi - if current=$(git rev-parse --verify $ref_stash 2>/dev/null) + if current=$(git rev-parse -q --verify $ref_stash) then git update-ref -d $ref_stash $current fi @@ -129,7 +129,7 @@ save_stash () { } have_stash () { - git rev-parse --verify $ref_stash >/dev/null 2>&1 + git rev-parse -q --verify $ref_stash >/dev/null } list_stash () { @@ -229,16 +229,16 @@ drop_stash () { fi # Verify supplied argument looks like a stash entry s=$(git rev-parse --verify "$@") && - git rev-parse --verify "$s:" > /dev/null 2>&1 && - git rev-parse --verify "$s^1:" > /dev/null 2>&1 && - git rev-parse --verify "$s^2:" > /dev/null 2>&1 || + git rev-parse -q --verify "$s:" > /dev/null && + git rev-parse -q --verify "$s^1:" > /dev/null && + git rev-parse -q --verify "$s^2:" > /dev/null || die "$*: not a valid stashed state" git reflog delete --updateref --rewrite "$@" && echo "Dropped $* ($s)" || die "$*: Could not drop stash entry" # clear_stash if we just dropped the last stash entry - git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash + git rev-parse -q --verify "$ref_stash@{0}" > /dev/null || clear_stash } apply_to_branch () { From 2dcb5e1ac87330b20962af9199a345eb378d3705 Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Mon, 1 Dec 2008 19:01:42 +0100 Subject: [PATCH 24/52] gitweb: Fix handling of non-ASCII characters in inserted HTML files Use new insert_file() subroutine to insert HTML chunks from external files: $site_header, $home_text (by default indextext.html), $site_footer, and $projectroot/$project/REAME.html. All non-ASCII chars of those files will be broken by Perl IO layer without decoding to utf8, so insert_file() does to_utf8() on each printed line; alternate solution would be to open those files with "binmode $fh, ':utf8'", or even all files with "use open qw(:std :utf8)". Note that inserting README.html lost one of checks for simplicity. Noticed-by: Tatsuki Sugiura Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 933e137386..b92134b1c0 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2740,6 +2740,15 @@ sub get_file_owner { return to_utf8($owner); } +# assume that file exists +sub insert_file { + my $filename = shift; + + open my $fd, '<', $filename; + print map(to_utf8, <$fd>); + close $fd; +} + ## ...................................................................... ## mimetype related functions @@ -2928,9 +2937,7 @@ EOF "\n"; if (-f $site_header) { - open (my $fd, $site_header); - print <$fd>; - close $fd; + insert_file($site_header); } print "
\n" . @@ -3017,9 +3024,7 @@ sub git_footer_html { print "
\n"; # class="page_footer" if (-f $site_footer) { - open (my $fd, $site_footer); - print <$fd>; - close $fd; + insert_file($site_footer); } print "\n" . @@ -4358,9 +4363,7 @@ sub git_project_list { git_header_html(); if (-f $home_text) { print "
\n"; - open (my $fd, $home_text); - print <$fd>; - close $fd; + insert_file($home_text); print "
\n"; } print $cgi->startform(-method => "get") . @@ -4472,13 +4475,10 @@ sub git_summary { print "\n"; if (-s "$projectroot/$project/README.html") { - if (open my $fd, "$projectroot/$project/README.html") { - print "
readme
\n" . - "
\n"; - print $_ while (<$fd>); - print "\n
\n"; # class="readme" - close $fd; - } + print "
readme
\n" . + "
\n"; + insert_file("$projectroot/$project/README.html"); + print "\n
\n"; # class="readme" } # we need to request one more than 16 (0..15) to check if From 733070bea9ce28d557f0b0950acc05b3fe6ff6c6 Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Fri, 7 Nov 2008 21:24:33 -0800 Subject: [PATCH 25/52] xdiff: give up scanning similar lines early In a corner case of large files whose lines do not match uniquely, the loop to eliminate a line that matches multiple locations adjacent to a run of lines that do not uniquely match wasted too much cycles. Fix this by giving up early after scanning 100 lines in both direction. Signed-off-by: Junio C Hamano --- xdiff/xprepare.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index e87ab57c65..a43aa72cd0 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -23,10 +23,9 @@ #include "xinclude.h" - #define XDL_KPDIS_RUN 4 #define XDL_MAX_EQLIMIT 1024 - +#define XDL_SIMSCAN_WINDOW 100 typedef struct s_xdlclass { @@ -312,6 +311,18 @@ void xdl_free_env(xdfenv_t *xe) { static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { long r, rdis0, rpdis0, rdis1, rpdis1; + /* + * Limits the window the is examined during the similar-lines + * scan. The loops below stops when dis[i - r] == 1 (line that + * has no match), but there are corner cases where the loop + * proceed all the way to the extremities by causing huge + * performance penalties in case of big files. + */ + if (i - s > XDL_SIMSCAN_WINDOW) + s = i - XDL_SIMSCAN_WINDOW; + if (e - i > XDL_SIMSCAN_WINDOW) + e = i + XDL_SIMSCAN_WINDOW; + /* * Scans the lines before 'i' to find a run of lines that either * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1). From 24b1f65fed0396497ae42c3c12390370819e8bc4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 3 Dec 2008 00:30:34 -0800 Subject: [PATCH 26/52] Install git-stage in exec-path Earlier the plan was to eventually eradicate git-foo executables from the filesystem for all the built-in commands, but when we released 1.6.0 we decided not to do so. Instead, it has been promised that by prepending the output from $(git --exec-path) to your $PATH, you can keep using the dashed form of commands. This also allows "git stage" to appear in the autogenerated command list, which is used to offer man pages by "git help" command. Signed-off-by: Junio C Hamano --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 9577d6fc73..51581973ab 100644 --- a/Makefile +++ b/Makefile @@ -320,6 +320,7 @@ BUILT_INS += git-merge-subtree$X BUILT_INS += git-peek-remote$X BUILT_INS += git-repo-config$X BUILT_INS += git-show$X +BUILT_INS += git-stage$X BUILT_INS += git-status$X BUILT_INS += git-whatchanged$X From a0fbc87cff6ae80c5b5be84201bc53252533b1fb Mon Sep 17 00:00:00 2001 From: Deskin Miller Date: Mon, 1 Dec 2008 21:43:00 -0500 Subject: [PATCH 27/52] git-svn: Make branch use correct svn-remote The 'branch' subcommand incorrectly had the svn-remote to use hardcoded as 'svn', the default remote name. This meant that branches derived from other svn-remotes would try to use the branch and tag configuration for the 'svn' remote, potentially copying would-be branches to the wrong place in SVN, into the branch namespace for another project. Fix this by using the remote name extracted from the svn info for the specified git ref. Add a testcase for this behaviour. [jc: squashed in a fix to test from Michael J Gruber for older svn (1.4)] Signed-off-by: Deskin Miller Acked-by: Eric Wong Signed-off-by: Junio C Hamano --- git-svn.perl | 2 +- t/t9128-git-svn-cmd-branch.sh | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/git-svn.perl b/git-svn.perl index 914c707a90..e64e97b4de 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -558,7 +558,7 @@ sub cmd_branch { my ($src, $rev, undef, $gs) = working_head_info($head); - my $remote = Git::SVN::read_all_remotes()->{svn}; + my $remote = Git::SVN::read_all_remotes()->{$gs->{repo_id}}; my $glob = $remote->{ $_tag ? 'tags' : 'branches' }; my ($lft, $rgt) = @{ $glob->{path} }{qw/left right/}; my $dst = join '/', $remote->{url}, $lft, $branch_name, ($rgt || ()); diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh index 47c4d4d938..252daa7e1a 100755 --- a/t/t9128-git-svn-cmd-branch.sh +++ b/t/t9128-git-svn-cmd-branch.sh @@ -56,4 +56,23 @@ test_expect_success 'git svn branch tests' ' test_must_fail git svn tag tag1 ' +test_expect_success 'branch uses correct svn-remote' ' + (svn co "$svnrepo" svn && + cd svn && + mkdir mirror && + svn add mirror && + svn copy trunk mirror/ && + svn copy tags mirror/ && + svn copy branches mirror/ && + svn ci -m "made mirror" ) && + rm -rf svn && + git svn init -s -R mirror --prefix=mirror/ "$svnrepo"/mirror && + git svn fetch -R mirror && + git checkout mirror/trunk && + base=$(git rev-parse HEAD:) && + git svn branch -m "branch in mirror" d && + test $base = $(git rev-parse remotes/mirror/d:) && + test_must_fail git rev-parse remotes/d +' + test_done From d69da76dd0bc352e358c4beb5eb3aae5588c99de Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:48 +0100 Subject: [PATCH 28/52] filter-branch: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-filter-branch.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-filter-branch.sh b/git-filter-branch.sh index 81392add0b..c106f45af7 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -256,7 +256,7 @@ while read commit parents; do *) # The commit may not have the subdirectory at all err=$(git read-tree -i -m $commit:"$filter_subdir" 2>&1) || { - if ! git rev-parse --verify $commit:"$filter_subdir" 2>/dev/null + if ! git rev-parse -q --verify $commit:"$filter_subdir" then rm -f "$GIT_INDEX_FILE" else From a86e8c1cfcb576d2d5b3a3499acc48684280dccb Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:49 +0100 Subject: [PATCH 29/52] lost-found: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-lost-found.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-lost-found.sh b/git-lost-found.sh index 9cedaf80ce..0b3e8c7a86 100755 --- a/git-lost-found.sh +++ b/git-lost-found.sh @@ -20,7 +20,7 @@ while read dangling type sha1 do case "$dangling" in dangling) - if git rev-parse --verify "$sha1^0" >/dev/null 2>/dev/null + if git rev-parse -q --verify "$sha1^0" >/dev/null then dir="$laf/commit" git show-branch "$sha1" From 2d17985782256d3505791a814b16e4e772fd341f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:50 +0100 Subject: [PATCH 30/52] pull: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-pull.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git-pull.sh b/git-pull.sh index 1cac898a24..2c7f432dc0 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -121,13 +121,13 @@ test true = "$rebase" && { test -z "$origin" && origin=$(get_default_remote) reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null | sed "s|refs/heads/\(.*\):|\1|")" && - oldremoteref="$(git rev-parse --verify \ - "refs/remotes/$origin/$reflist" 2>/dev/null)" + oldremoteref="$(git rev-parse -q --verify \ + "refs/remotes/$origin/$reflist")" } -orig_head=$(git rev-parse --verify HEAD 2>/dev/null) +orig_head=$(git rev-parse -q --verify HEAD) git fetch $verbosity --update-head-ok "$@" || exit 1 -curr_head=$(git rev-parse --verify HEAD 2>/dev/null) +curr_head=$(git rev-parse -q --verify HEAD) if test -n "$orig_head" && test "$curr_head" != "$orig_head" then # The fetch involved updating the current branch. From 5a92d190211c5f1277ea76752882a5f1104488f8 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:51 +0100 Subject: [PATCH 31/52] rebase: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-rebase.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/git-rebase.sh b/git-rebase.sh index 023a6dc94a..ea7720d3e2 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -365,10 +365,10 @@ case "$#" in switch_to="$2" if git show-ref --verify --quiet -- "refs/heads/$2" && - branch=$(git rev-parse --verify "refs/heads/$2" 2>/dev/null) + branch=$(git rev-parse -q --verify "refs/heads/$2") then head_name="refs/heads/$2" - elif branch=$(git rev-parse --verify "$2" 2>/dev/null) + elif branch=$(git rev-parse -q --verify "$2") then head_name="detached HEAD" else From 30353a40f7ca2f09e61013609f4847461b4544b7 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 3 Dec 2008 14:26:52 +0100 Subject: [PATCH 32/52] submodule: use git rev-parse -q Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- git-submodule.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git-submodule.sh b/git-submodule.sh index 220d94ec0c..2f47e065fe 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -413,7 +413,7 @@ cmd_summary() { test $summary_limit = 0 && return - if rev=$(git rev-parse --verify "$1^0" 2>/dev/null) + if rev=$(git rev-parse -q --verify "$1^0") then head=$rev shift @@ -464,11 +464,11 @@ cmd_summary() { missing_dst= test $mod_src = 160000 && - ! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_src^0 >/dev/null 2>&1 && + ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_src^0 >/dev/null && missing_src=t test $mod_dst = 160000 && - ! GIT_DIR="$name/.git" git-rev-parse --verify $sha1_dst^0 >/dev/null 2>&1 && + ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_dst^0 >/dev/null && missing_dst=t total_commits= From c76b4c81e79f423c3d50f0cfadcf74de3bee8aea Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 3 Dec 2008 22:42:03 -0500 Subject: [PATCH 33/52] add stage to gitignore This is a generated builtin since 24b1f65f (Install git-stage in exec-path). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bbaf9de0bc..d9adce585a 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,7 @@ git-show git-show-branch git-show-index git-show-ref +git-stage git-stash git-status git-stripspace From 47d32af2338418275ab6b53a737952af22289d97 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 5 Dec 2008 01:35:48 +0100 Subject: [PATCH 34/52] Make some of fwrite/fclose/write/close failures visible So that full filesystem conditions or permissions problems won't go unnoticed. Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- builtin-fsck.c | 8 ++++++-- builtin-merge.c | 6 ++++-- rerere.c | 46 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/builtin-fsck.c b/builtin-fsck.c index d3f3de9446..afded5e68d 100644 --- a/builtin-fsck.c +++ b/builtin-fsck.c @@ -201,12 +201,16 @@ static void check_unreachable_object(struct object *obj) char *buf = read_sha1_file(obj->sha1, &type, &size); if (buf) { - fwrite(buf, size, 1, f); + if (fwrite(buf, size, 1, f) != 1) + die("Could not write %s: %s", + filename, strerror(errno)); free(buf); } } else fprintf(f, "%s\n", sha1_to_hex(obj->sha1)); - fclose(f); + if (fclose(f)) + die("Could not finish %s: %s", + filename, strerror(errno)); } return; } diff --git a/builtin-merge.c b/builtin-merge.c index 7c2b90c70b..cf869751b4 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -293,8 +293,10 @@ static void squash_message(void) pretty_print_commit(rev.commit_format, commit, &out, rev.abbrev, NULL, NULL, rev.date_mode, 0); } - write(fd, out.buf, out.len); - close(fd); + if (write(fd, out.buf, out.len) < 0) + die("Writing SQUASH_MSG: %s", strerror(errno)); + if (close(fd)) + die("Finishing SQUASH_MSG: %s", strerror(errno)); strbuf_release(&out); } diff --git a/rerere.c b/rerere.c index 02931a151f..718fb526dd 100644 --- a/rerere.c +++ b/rerere.c @@ -70,6 +70,19 @@ static int write_rr(struct string_list *rr, int out_fd) return 0; } +static void ferr_write(const void *p, size_t count, FILE *fp, int *err) +{ + if (!count || *err) + return; + if (fwrite(p, count, 1, fp) != 1) + *err = errno; +} + +static inline void ferr_puts(const char *s, FILE *fp, int *err) +{ + ferr_write(s, strlen(s), fp, err); +} + static int handle_file(const char *path, unsigned char *sha1, const char *output) { @@ -82,6 +95,7 @@ static int handle_file(const char *path, struct strbuf one = STRBUF_INIT, two = STRBUF_INIT; FILE *f = fopen(path, "r"); FILE *out = NULL; + int wrerror = 0; if (!f) return error("Could not open %s", path); @@ -118,11 +132,11 @@ static int handle_file(const char *path, hunk_no++; hunk = RR_CONTEXT; if (out) { - fputs("<<<<<<<\n", out); - fwrite(one.buf, one.len, 1, out); - fputs("=======\n", out); - fwrite(two.buf, two.len, 1, out); - fputs(">>>>>>>\n", out); + ferr_puts("<<<<<<<\n", out, &wrerror); + ferr_write(one.buf, one.len, out, &wrerror); + ferr_puts("=======\n", out, &wrerror); + ferr_write(two.buf, two.len, out, &wrerror); + ferr_puts(">>>>>>>\n", out, &wrerror); } if (sha1) { git_SHA1_Update(&ctx, one.buf ? one.buf : "", @@ -139,7 +153,7 @@ static int handle_file(const char *path, else if (hunk == RR_SIDE_2) strbuf_addstr(&two, buf); else if (out) - fputs(buf, out); + ferr_puts(buf, out, &wrerror); continue; bad: hunk = 99; /* force error exit */ @@ -149,8 +163,12 @@ static int handle_file(const char *path, strbuf_release(&two); fclose(f); - if (out) - fclose(out); + if (wrerror) + error("There were errors while writing %s (%s)", + path, strerror(wrerror)); + if (out && fclose(out)) + wrerror = error("Failed to flush %s: %s", + path, strerror(errno)); if (sha1) git_SHA1_Final(sha1, &ctx); if (hunk != RR_CONTEXT) { @@ -158,6 +176,8 @@ static int handle_file(const char *path, unlink(output); return error("Could not parse conflict hunks in %s", path); } + if (wrerror) + return -1; return hunk_no; } @@ -200,9 +220,13 @@ static int merge(const char *name, const char *path) if (!ret) { FILE *f = fopen(path, "w"); if (!f) - return error("Could not write to %s", path); - fwrite(result.ptr, result.size, 1, f); - fclose(f); + return error("Could not open %s: %s", path, + strerror(errno)); + if (fwrite(result.ptr, result.size, 1, f) != 1) + error("Could not write %s: %s", path, strerror(errno)); + if (fclose(f)) + return error("Writing %s failed: %s", path, + strerror(errno)); } free(cur.ptr); From 7be77de266b5cbcbd28d69a04df6f0b167b87cf6 Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 5 Dec 2008 01:36:46 +0100 Subject: [PATCH 35/52] Make chdir failures visible Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- git.c | 4 ++-- setup.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/git.c b/git.c index 9e5813cc92..940a498962 100644 --- a/git.c +++ b/git.c @@ -195,8 +195,8 @@ static int handle_alias(int *argcp, const char ***argv) ret = 1; } - if (subdir) - chdir(subdir); + if (subdir && chdir(subdir)) + die("Cannot change to %s: %s", subdir, strerror(errno)); errno = saved_errno; diff --git a/setup.c b/setup.c index 78a8041ff0..833ced2269 100644 --- a/setup.c +++ b/setup.c @@ -470,7 +470,8 @@ const char *setup_git_directory_gently(int *nongit_ok) } die("Not a git repository"); } - chdir(".."); + if (chdir("..")) + die("Cannot change to %s/..: %s", cwd, strerror(errno)); } inside_git_dir = 0; From 304dcf262e3f8524c909a13cf73a67522be6353b Mon Sep 17 00:00:00 2001 From: Alex Riesen Date: Fri, 5 Dec 2008 01:39:14 +0100 Subject: [PATCH 36/52] Report symlink failures in merge-recursive Signed-off-by: Alex Riesen Signed-off-by: Junio C Hamano --- merge-recursive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/merge-recursive.c b/merge-recursive.c index 0e988f2a00..a0c804c817 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -525,7 +525,8 @@ static void update_file_flags(struct merge_options *o, char *lnk = xmemdupz(buf, size); safe_create_leading_directories_const(path); unlink(path); - symlink(lnk, path); + if (symlink(lnk, path)) + die("failed to symlink %s: %s", path, strerror(errno)); free(lnk); } else die("do not know what to do with %06o %s '%s'", From 7f705dc3686c2b1c77172b6847c1406eb66a20c3 Mon Sep 17 00:00:00 2001 From: Tor Arvid Lund Date: Thu, 4 Dec 2008 14:37:33 +0100 Subject: [PATCH 37/52] git-p4: Fix bug in p4Where method. When running: p4 where //depot/SomePath/... The result can in some situations look like: //depot/SomePath/... //client/SomePath/... /home/user/p4root/SomePath/... -//depot/SomePath/UndesiredSubdir/... //client/SomePath/UndesiredSubdir/... /home/user/p4root/SomePath/UndesiredSubdir/... This depends on the users Client view. The current p4Where method will now return /home/user/p4root/SomePath/UndesiredSubdir/... which is not what we want. This patch loops through the results from "p4 where", and picks the one where the depotFile exactly matches the given depotPath (//depot/SomePath/... in this example). Signed-off-by: Tor Arvid Lund Signed-off-by: Junio C Hamano --- contrib/fast-import/git-p4 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4 index b44fbfc9b3..ee504e90ed 100755 --- a/contrib/fast-import/git-p4 +++ b/contrib/fast-import/git-p4 @@ -245,7 +245,15 @@ def p4Cmd(cmd): def p4Where(depotPath): if not depotPath.endswith("/"): depotPath += "/" - output = p4Cmd("where %s..." % depotPath) + depotPath = depotPath + "..." + outputList = p4CmdList("where %s" % depotPath) + output = None + for entry in outputList: + if entry["depotFile"] == depotPath: + output = entry + break + if output == None: + return "" if output["code"] == "error": return "" clientPath = "" From 1556ef1e373e2928cd0d4a3630f142a57c1f1813 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 4 Dec 2008 15:03:28 -0800 Subject: [PATCH 38/52] git-am --whitespace: do not lose the command line option When you start "git am --whitespace=fix" and the patch application process is interrupted by an unapplicable patch early in the series, after fixing the offending patch, the remainder of the patch should be processed still with --whitespace=fix when restarted with "git am --resolved" (or dropping the offending patch with "git am --skip"). The breakage was introduced by the commit 67dad68 (add -C[NUM] to git-am, 2007-02-08); this should fix it. Signed-off-by: Junio C Hamano --- git-am.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/git-am.sh b/git-am.sh index aa602618e6..1bf70d4777 100755 --- a/git-am.sh +++ b/git-am.sh @@ -121,7 +121,7 @@ It does not apply to blobs recorded in its index." prec=4 dotest="$GIT_DIR/rebase-apply" -sign= utf8=t keep= skip= interactive= resolved= rebasing= abort= +sign= utf8=t keep= skip= interactive= resolved= rebasing= abort= ws= resolvemsg= resume= git_apply_opt= @@ -156,7 +156,7 @@ do --resolvemsg) shift; resolvemsg=$1 ;; --whitespace) - git_apply_opt="$git_apply_opt $1=$2"; shift ;; + ws="--whitespace=$2"; shift ;; -C|-p) git_apply_opt="$git_apply_opt $1$2"; shift ;; --) @@ -283,7 +283,7 @@ if test "$(cat "$dotest/keep")" = t then keep=-k fi -ws=`cat "$dotest/whitespace"` +ws=$(cat "$dotest/whitespace") if test "$(cat "$dotest/sign")" = t then SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e ' @@ -454,7 +454,7 @@ do case "$resolved" in '') - git apply $git_apply_opt --index "$dotest/patch" + git apply $git_apply_opt $ws --index "$dotest/patch" apply_status=$? ;; t) From a20033796b312390ea8a50917bea623efd6fad97 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 4 Dec 2008 15:38:27 -0800 Subject: [PATCH 39/52] git-am: propagate -C, -p options as well These options are meant to deal with patches that do not apply cleanly due to the differences between the version the patch was based on and the version "git am" is working on. Because a series of patches applied in the same "git am" run tends to come from the same source, it is more useful to propagate these options after the application stops. Signed-off-by: Junio C Hamano --- git-am.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/git-am.sh b/git-am.sh index 1bf70d4777..ed54e716d9 100755 --- a/git-am.sh +++ b/git-am.sh @@ -121,7 +121,7 @@ It does not apply to blobs recorded in its index." prec=4 dotest="$GIT_DIR/rebase-apply" -sign= utf8=t keep= skip= interactive= resolved= rebasing= abort= ws= +sign= utf8=t keep= skip= interactive= resolved= rebasing= abort= resolvemsg= resume= git_apply_opt= @@ -156,7 +156,7 @@ do --resolvemsg) shift; resolvemsg=$1 ;; --whitespace) - ws="--whitespace=$2"; shift ;; + git_apply_opt="$git_apply_opt $1=$2"; shift ;; -C|-p) git_apply_opt="$git_apply_opt $1$2"; shift ;; --) @@ -247,10 +247,10 @@ else exit 1 } - # -s, -u, -k and --whitespace flags are kept for the - # resuming session after a patch failure. + # -s, -u, -k, --whitespace, -C and -p flags are kept + # for the resuming session after a patch failure. # -3 and -i can and must be given when resuming. - echo " $ws" >"$dotest/whitespace" + echo " $git_apply_opt" >"$dotest/apply_opt_extra" echo "$sign" >"$dotest/sign" echo "$utf8" >"$dotest/utf8" echo "$keep" >"$dotest/keep" @@ -283,7 +283,7 @@ if test "$(cat "$dotest/keep")" = t then keep=-k fi -ws=$(cat "$dotest/whitespace") +git_apply_opt=$(cat "$dotest/apply_opt_extra") if test "$(cat "$dotest/sign")" = t then SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e ' @@ -454,7 +454,7 @@ do case "$resolved" in '') - git apply $git_apply_opt $ws --index "$dotest/patch" + git apply $git_apply_opt --index "$dotest/patch" apply_status=$? ;; t) From 22db240dd1791b32e7f6d25a466c2835bdccb51e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 4 Dec 2008 15:38:27 -0800 Subject: [PATCH 40/52] git-am: propagate --3way options as well The reasoning is the same as the previous patch, where we made -C and -p propagate across a failure. Signed-off-by: Junio C Hamano --- git-am.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/git-am.sh b/git-am.sh index ed54e716d9..13c02d6ade 100755 --- a/git-am.sh +++ b/git-am.sh @@ -247,10 +247,11 @@ else exit 1 } - # -s, -u, -k, --whitespace, -C and -p flags are kept + # -s, -u, -k, --whitespace, -3, -C and -p flags are kept # for the resuming session after a patch failure. - # -3 and -i can and must be given when resuming. + # -i can and must be given when resuming. echo " $git_apply_opt" >"$dotest/apply_opt_extra" + echo "$threeway" >"$dotest/threeway" echo "$sign" >"$dotest/sign" echo "$utf8" >"$dotest/utf8" echo "$keep" >"$dotest/keep" @@ -283,6 +284,10 @@ if test "$(cat "$dotest/keep")" = t then keep=-k fi +if test "$(cat "$dotest/threeway")" = t +then + threeway=t +fi git_apply_opt=$(cat "$dotest/apply_opt_extra") if test "$(cat "$dotest/sign")" = t then From fe6beab7e80565dac81125aa82521f7673905ebc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 4 Dec 2008 17:08:48 -0800 Subject: [PATCH 41/52] Test that git-am does not lose -C/-p/--whitespace options These tests make sure that "git am" does not lose command line options specified when it was started, after it is interrupted by a patch that does not apply earlier in the series. Signed-off-by: Junio C Hamano --- t/t4252-am-options.sh | 54 +++++++++++++++++++++++++++++++++++++++++++ t/t4252/am-test-1-1 | 19 +++++++++++++++ t/t4252/am-test-1-2 | 21 +++++++++++++++++ t/t4252/am-test-2-1 | 19 +++++++++++++++ t/t4252/am-test-2-2 | 21 +++++++++++++++++ t/t4252/am-test-3-1 | 19 +++++++++++++++ t/t4252/am-test-3-2 | 21 +++++++++++++++++ t/t4252/am-test-4-1 | 19 +++++++++++++++ t/t4252/am-test-4-2 | 22 ++++++++++++++++++ t/t4252/file-1-0 | 7 ++++++ t/t4252/file-2-0 | 7 ++++++ 11 files changed, 229 insertions(+) create mode 100755 t/t4252-am-options.sh create mode 100644 t/t4252/am-test-1-1 create mode 100644 t/t4252/am-test-1-2 create mode 100644 t/t4252/am-test-2-1 create mode 100644 t/t4252/am-test-2-2 create mode 100644 t/t4252/am-test-3-1 create mode 100644 t/t4252/am-test-3-2 create mode 100644 t/t4252/am-test-4-1 create mode 100644 t/t4252/am-test-4-2 create mode 100644 t/t4252/file-1-0 create mode 100644 t/t4252/file-2-0 diff --git a/t/t4252-am-options.sh b/t/t4252-am-options.sh new file mode 100755 index 0000000000..1a1946dd97 --- /dev/null +++ b/t/t4252-am-options.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +test_description='git am not losing options' +. ./test-lib.sh + +tm="$TEST_DIRECTORY/t4252" + +test_expect_success setup ' + cp "$tm/file-1-0" file-1 && + cp "$tm/file-2-0" file-2 && + git add file-1 file-2 && + test_tick && + git commit -m initial && + git tag initial +' + +test_expect_success 'interrupted am --whitespace=fix' ' + rm -rf .git/rebase-apply && + git reset --hard initial && + test_must_fail git am --whitespace=fix "$tm"/am-test-1-? && + git am --skip && + grep 3 file-1 && + grep "^Six$" file-2 +' + +test_expect_success 'interrupted am -C1' ' + rm -rf .git/rebase-apply && + git reset --hard initial && + test_must_fail git am -C1 "$tm"/am-test-2-? && + git am --skip && + grep 3 file-1 && + grep "^Three$" file-2 +' + +test_expect_success 'interrupted am -p2' ' + rm -rf .git/rebase-apply && + git reset --hard initial && + test_must_fail git am -p2 "$tm"/am-test-3-? && + git am --skip && + grep 3 file-1 && + grep "^Three$" file-2 +' + +test_expect_success 'interrupted am -C1 -p2' ' + rm -rf .git/rebase-apply && + git reset --hard initial && + test_must_fail git am -p2 -C1 "$tm"/am-test-4-? && + cat .git/rebase-apply/apply_opt_extra && + git am --skip && + grep 3 file-1 && + grep "^Three$" file-2 +' + +test_done diff --git a/t/t4252/am-test-1-1 b/t/t4252/am-test-1-1 new file mode 100644 index 0000000000..b0c09dc965 --- /dev/null +++ b/t/t4252/am-test-1-1 @@ -0,0 +1,19 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Three + +Application of this should be rejected because the first line in the +context does not match. + +diff --git i/file-1 w/file-1 +index 06e567b..10f8342 100644 +--- i/file-1 ++++ w/file-1 +@@ -1,6 +1,6 @@ + One + 2 +-3 ++Three + 4 + 5 + 6 diff --git a/t/t4252/am-test-1-2 b/t/t4252/am-test-1-2 new file mode 100644 index 0000000000..1b874ae115 --- /dev/null +++ b/t/t4252/am-test-1-2 @@ -0,0 +1,21 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Six + +Applying this patch with --whitespace=fix should lose +the trailing whitespace after "Six". + +diff --git i/file-2 w/file-2 +index 06e567b..b6f3a16 100644 +--- i/file-2 ++++ w/file-2 +@@ -1,7 +1,7 @@ + 1 + 2 +-3 ++Three + 4 + 5 +-6 ++Six + 7 diff --git a/t/t4252/am-test-2-1 b/t/t4252/am-test-2-1 new file mode 100644 index 0000000000..feda94a0cc --- /dev/null +++ b/t/t4252/am-test-2-1 @@ -0,0 +1,19 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Three + +Application of this should be rejected even with -C1 because the +preimage line in the context does not match. + +diff --git i/file-1 w/file-1 +index 06e567b..10f8342 100644 +--- i/file-1 ++++ w/file-1 +@@ -1,6 +1,6 @@ + 1 + 2 +-Tres ++Three + 4 + 5 + 6 diff --git a/t/t4252/am-test-2-2 b/t/t4252/am-test-2-2 new file mode 100644 index 0000000000..2ac6600976 --- /dev/null +++ b/t/t4252/am-test-2-2 @@ -0,0 +1,21 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Six + +Applying this patch with -C1 should be successful even though +the first line in the context does not match. + +diff --git i/file-2 w/file-2 +index 06e567b..b6f3a16 100644 +--- i/file-2 ++++ w/file-2 +@@ -1,7 +1,7 @@ + One + 2 +-3 ++Three + 4 + 5 +-6 ++Six + 7 diff --git a/t/t4252/am-test-3-1 b/t/t4252/am-test-3-1 new file mode 100644 index 0000000000..608e5abba4 --- /dev/null +++ b/t/t4252/am-test-3-1 @@ -0,0 +1,19 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Three + +Application of this should be rejected even with -p2 because the +preimage line in the context does not match. + +diff --git i/junk/file-1 w/junk/file-1 +index 06e567b..10f8342 100644 +--- i/junk/file-1 ++++ w/junk/file-1 +@@ -1,6 +1,6 @@ + 1 + 2 +-Tres ++Three + 4 + 5 + 6 diff --git a/t/t4252/am-test-3-2 b/t/t4252/am-test-3-2 new file mode 100644 index 0000000000..0081b96f2a --- /dev/null +++ b/t/t4252/am-test-3-2 @@ -0,0 +1,21 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Six + +Applying this patch with -p2 should be successful even though +the patch is against a wrong level. + +diff --git i/junk/file-2 w/junk/file-2 +index 06e567b..b6f3a16 100644 +--- i/junk/file-2 ++++ w/junk/file-2 +@@ -1,7 +1,7 @@ + 1 + 2 +-3 ++Three + 4 + 5 +-6 ++Six + 7 diff --git a/t/t4252/am-test-4-1 b/t/t4252/am-test-4-1 new file mode 100644 index 0000000000..e48cd6cbde --- /dev/null +++ b/t/t4252/am-test-4-1 @@ -0,0 +1,19 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Three + +Application of this should be rejected even with -C1 -p2 because +the preimage line in the context does not match. + +diff --git i/junk/file-1 w/junk/file-1 +index 06e567b..10f8342 100644 +--- i/junk/file-1 ++++ w/junk/file-1 +@@ -1,6 +1,6 @@ + 1 + 2 +-Tres ++Three + 4 + 5 + 6 diff --git a/t/t4252/am-test-4-2 b/t/t4252/am-test-4-2 new file mode 100644 index 0000000000..0e69bfa55b --- /dev/null +++ b/t/t4252/am-test-4-2 @@ -0,0 +1,22 @@ +From: A U Thor +Date: Thu Dec 4 16:00:00 2008 -0800 +Subject: Six + +Applying this patch with -C1 -p2 should be successful even though +the patch is against a wrong level and the first context line does +not match. + +diff --git i/junk/file-2 w/junk/file-2 +index 06e567b..b6f3a16 100644 +--- i/junk/file-2 ++++ w/junk/file-2 +@@ -1,7 +1,7 @@ + One + 2 +-3 ++Three + 4 + 5 +-6 ++Six + 7 diff --git a/t/t4252/file-1-0 b/t/t4252/file-1-0 new file mode 100644 index 0000000000..06e567b11d --- /dev/null +++ b/t/t4252/file-1-0 @@ -0,0 +1,7 @@ +1 +2 +3 +4 +5 +6 +7 diff --git a/t/t4252/file-2-0 b/t/t4252/file-2-0 new file mode 100644 index 0000000000..06e567b11d --- /dev/null +++ b/t/t4252/file-2-0 @@ -0,0 +1,7 @@ +1 +2 +3 +4 +5 +6 +7 From 9b9f5a2258e6df611d2903d84fd8d41806ce0e00 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 5 Dec 2008 11:19:43 -0800 Subject: [PATCH 42/52] git-am: rename apply_opt_extra file to apply-opt All other state files use dash in their names, not underscores. Also, there is no reason to call this "extra". Drop it. Signed-off-by: Junio C Hamano --- git-am.sh | 4 ++-- t/t4252-am-options.sh | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/git-am.sh b/git-am.sh index 13c02d6ade..4b157fe5d5 100755 --- a/git-am.sh +++ b/git-am.sh @@ -250,7 +250,7 @@ else # -s, -u, -k, --whitespace, -3, -C and -p flags are kept # for the resuming session after a patch failure. # -i can and must be given when resuming. - echo " $git_apply_opt" >"$dotest/apply_opt_extra" + echo " $git_apply_opt" >"$dotest/apply-opt" echo "$threeway" >"$dotest/threeway" echo "$sign" >"$dotest/sign" echo "$utf8" >"$dotest/utf8" @@ -288,7 +288,7 @@ if test "$(cat "$dotest/threeway")" = t then threeway=t fi -git_apply_opt=$(cat "$dotest/apply_opt_extra") +git_apply_opt=$(cat "$dotest/apply-opt") if test "$(cat "$dotest/sign")" = t then SIGNOFF=`git var GIT_COMMITTER_IDENT | sed -e ' diff --git a/t/t4252-am-options.sh b/t/t4252-am-options.sh index 1a1946dd97..3ab9e8e6e3 100755 --- a/t/t4252-am-options.sh +++ b/t/t4252-am-options.sh @@ -45,7 +45,6 @@ test_expect_success 'interrupted am -C1 -p2' ' rm -rf .git/rebase-apply && git reset --hard initial && test_must_fail git am -p2 -C1 "$tm"/am-test-4-? && - cat .git/rebase-apply/apply_opt_extra && git am --skip && grep 3 file-1 && grep "^Three$" file-2 From 2dd620286e84e4e76226a3511af6d14755b8c809 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 5 Dec 2008 20:02:55 -0800 Subject: [PATCH 43/52] Update draft release notes to 1.6.1 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.1.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/RelNotes-1.6.1.txt b/Documentation/RelNotes-1.6.1.txt index 698c1e0b77..9f5c0b5584 100644 --- a/Documentation/RelNotes-1.6.1.txt +++ b/Documentation/RelNotes-1.6.1.txt @@ -69,12 +69,18 @@ on. * "git add -N path..." adds the named paths as an empty blob, so that subsequent "git diff" will show a diff as if they are creation events. +* "git add" gained a built-in synonym for people who want to say "stage + changes" instead of "add contents the the staging area" which amounts + to the same thing. + * "git apply" learned --include=paths option, similar to the existing --exclude=paths option. * "git bisect" is careful about a user mistake and suggests testing of merge base first when good is not a strict ancestor of bad. +* "git bisect skip" can take a range of commits. + * "git blame" re-encodes the commit metainfo to UTF-8 from i18n.commitEncoding by default. @@ -238,6 +244,9 @@ release, unless otherwise noted. it (we still need to fix a similar nonsense when S is a submodule and F is a path in it). +* "git am" after stopping at a broken patch lost --whitespace, -C, -p and + --3way options given from the command line initially. + * "git diff --stdin" used to take two trees on a line and compared them, but we dropped support for such a use case long time ago. This has been resurrected. @@ -252,6 +261,10 @@ release, unless otherwise noted. * "git repack" used to grab objects out of packs marked with .keep into a new pack (fix scheduled to be further downmerged to maint). +* "git rm --cached" used to allow an empty blob that was added earlier to + be removed without --force, even when the file in the work tree has + since been modified. + * "git push --tags --all $there" failed with generic usage message without telling saying these two options are incompatible. @@ -263,8 +276,11 @@ release, unless otherwise noted. large file with many repeated contents (fix scheduled to be further cherry- picked to maint). +* "gitweb" did not mark non-ASCII characters imported from external HTML fragments + correctly. + -- exec >/var/tmp/1 -O=v1.6.0.4-854-gaaab7ea +O=v1.6.1-rc1-55-gd8af75d echo O=$(git describe master) git shortlog --no-merges $O..master ^maint From d551bbaf3af1fad947c704bdeb9cf664b34e38c6 Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Sat, 6 Dec 2008 21:50:09 +0100 Subject: [PATCH 44/52] fetch-pack: Avoid memcpy() with src==dst memcpy() may only be used for disjoint memory areas, but when invoked from cmd_fetch_pack(), we have my_args == &args. (The argument cannot be removed entirely because transport.c invokes with its own variable.) Signed-off-by: Thomas Rast Signed-off-by: Junio C Hamano --- builtin-fetch-pack.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c index 21ce3e0163..22a57121a8 100644 --- a/builtin-fetch-pack.c +++ b/builtin-fetch-pack.c @@ -780,7 +780,8 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args, struct ref *ref_cpy; fetch_pack_setup(); - memcpy(&args, my_args, sizeof(args)); + if (&args != my_args) + memcpy(&args, my_args, sizeof(args)); if (args.depth > 0) { if (stat(git_path("shallow"), &st)) st.st_mtime = 0; From e4a80ecf40c9651741def7c4f0b2ca56b42af1a8 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 7 Dec 2008 01:45:37 +0100 Subject: [PATCH 45/52] http.c: use 'git_config_string' to get 'curl_http_proxy' Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- http.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/http.c b/http.c index a97fdf5117..c18e30abe8 100644 --- a/http.c +++ b/http.c @@ -24,7 +24,7 @@ static const char *ssl_cainfo = NULL; static long curl_low_speed_limit = -1; static long curl_low_speed_time = -1; static int curl_ftp_no_epsv = 0; -static char *curl_http_proxy = NULL; +static const char *curl_http_proxy = NULL; static struct curl_slist *pragma_header; @@ -149,11 +149,8 @@ static int http_options(const char *var, const char *value, void *cb) return 0; } if (!strcmp("http.proxy", var)) { - if (curl_http_proxy == NULL) { - if (!value) - return config_error_nonbool(var); - curl_http_proxy = xstrdup(value); - } + if (curl_http_proxy == NULL) + return git_config_string(&curl_http_proxy, var, value); return 0; } @@ -309,7 +306,7 @@ void http_cleanup(void) pragma_header = NULL; if (curl_http_proxy) { - free(curl_http_proxy); + free((void *)curl_http_proxy); curl_http_proxy = NULL; } } From bcc6a833032e0830195c1de1b834006a1d0156fe Mon Sep 17 00:00:00 2001 From: Jakub Narebski Date: Sun, 7 Dec 2008 10:36:36 +0100 Subject: [PATCH 46/52] gitweb: Make project specific override for 'grep' feature work The 'grep' feature was marked in the comments as having project specific config, but it lacked 'sub' key required for it to work. Kind-of-Noticed-by: Matt Kraai Signed-off-by: Jakub Narebski Signed-off-by: Junio C Hamano --- gitweb/gitweb.perl | 1 + 1 file changed, 1 insertion(+) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index eae5084c66..ced7bb740f 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -232,6 +232,7 @@ our %feature = ( # $feature{'grep'}{'override'} = 1; # and in project config gitweb.grep = 0|1; 'grep' => { + 'sub' => \&feature_grep, 'override' => 0, 'default' => [1]}, From 3927bbe9a4d4033551dea39ac1abb9cdc45d822c Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 6 Dec 2008 14:40:34 -0500 Subject: [PATCH 47/52] tag: delete TAG_EDITMSG only on successful tag The user may put some effort into writing an annotated tag message. When the tagging process later fails (which can happen fairly easily, since it may be dependent on gpg being correctly configured and used), there is no record left on disk of the tag message. Instead, let's keep the TAG_EDITMSG file around until we are sure the tag has been created successfully. If we die because of an error, the user can recover their text from that file. Leaving the file in place causes no conflicts; it will be silently overwritten by the next annotated tag creation. This matches the behavior of COMMIT_EDITMSG, which stays around in case of error. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin-tag.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/builtin-tag.c b/builtin-tag.c index 11b91b3c3b..2cdefb1d9a 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -253,6 +253,15 @@ static void write_tag_body(int fd, const unsigned char *sha1) free(buf); } +static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result) +{ + if (sign && do_sign(buf) < 0) + return error("unable to sign the tag"); + if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0) + return error("unable to write tag file"); + return 0; +} + static void create_tag(const unsigned char *object, const char *tag, struct strbuf *buf, int message, int sign, unsigned char *prev, unsigned char *result) @@ -260,6 +269,7 @@ static void create_tag(const unsigned char *object, const char *tag, enum object_type type; char header_buf[1024]; int header_len; + char *path = NULL; type = sha1_object_info(object, NULL); if (type <= OBJ_NONE) @@ -279,7 +289,6 @@ static void create_tag(const unsigned char *object, const char *tag, die("tag header too big."); if (!message) { - char *path; int fd; /* write the template message before editing: */ @@ -300,9 +309,6 @@ static void create_tag(const unsigned char *object, const char *tag, "Please supply the message using either -m or -F option.\n"); exit(1); } - - unlink(path); - free(path); } stripspace(buf, 1); @@ -312,10 +318,16 @@ static void create_tag(const unsigned char *object, const char *tag, strbuf_insert(buf, 0, header_buf, header_len); - if (sign && do_sign(buf) < 0) - die("unable to sign the tag"); - if (write_sha1_file(buf->buf, buf->len, tag_type, result) < 0) - die("unable to write tag file"); + if (build_tag_object(buf, sign, result) < 0) { + if (path) + fprintf(stderr, "The tag message has been left in %s\n", + path); + exit(128); + } + if (path) { + unlink(path); + free(path); + } } struct msg_arg { From dbc2fb6b841dd3a72c52a5a161e2362a26fc65f5 Mon Sep 17 00:00:00 2001 From: Matt McCutchen Date: Fri, 10 Oct 2008 21:56:15 -0400 Subject: [PATCH 48/52] "git diff {3,}": do not reverse order of arguments According to the message of commit 0fe7c1de16f71312e6adac4b85bddf0d62a47168, "git diff" with three or more trees expects the merged tree first followed by the parents, in order. However, this command reversed the order of its arguments, resulting in confusing diffs. A comment /* Again, the revs are all reverse */ suggested there was a reason for this, but I can't figure out the reason, so I removed the reversal of the arguments. Test case included. Signed-off-by: Matt McCutchen Signed-off-by: Shawn O. Pearce --- builtin-diff.c | 4 +--- t/t4013-diff-various.sh | 1 + t/t4013/diff.diff_master_master^_side | 29 +++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 t/t4013/diff.diff_master_master^_side diff --git a/builtin-diff.c b/builtin-diff.c index 26cf678591..375a0d3302 100644 --- a/builtin-diff.c +++ b/builtin-diff.c @@ -175,10 +175,8 @@ static int builtin_diff_combined(struct rev_info *revs, if (!revs->dense_combined_merges && !revs->combine_merges) revs->dense_combined_merges = revs->combine_merges = 1; parent = xmalloc(ents * sizeof(*parent)); - /* Again, the revs are all reverse */ for (i = 0; i < ents; i++) - hashcpy((unsigned char *)(parent + i), - ent[ents - 1 - i].item->sha1); + hashcpy((unsigned char *)(parent + i), ent[i].item->sha1); diff_tree_combined(parent[0], parent + 1, ents - 1, revs->dense_combined_merges, revs); return 0; diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 9337b81064..99d9e0ba13 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -258,6 +258,7 @@ diff --patch-with-stat -r initial..side diff --patch-with-raw -r initial..side diff --name-status dir2 dir diff --no-index --name-status dir2 dir +diff master master^ side EOF test_done diff --git a/t/t4013/diff.diff_master_master^_side b/t/t4013/diff.diff_master_master^_side new file mode 100644 index 0000000000..50ec9cadd6 --- /dev/null +++ b/t/t4013/diff.diff_master_master^_side @@ -0,0 +1,29 @@ +$ git diff master master^ side +diff --cc dir/sub +index cead32e,7289e35..992913c +--- a/dir/sub ++++ b/dir/sub +@@@ -1,6 -1,4 +1,8 @@@ + A + B + +C + +D + +E + +F ++ 1 ++ 2 +diff --cc file0 +index b414108,f4615da..10a8a9f +--- a/file0 ++++ b/file0 +@@@ -1,6 -1,6 +1,9 @@@ + 1 + 2 + 3 + +4 + +5 + +6 ++ A ++ B ++ C +$ From 1c2ed59de2d14ad6ee9daa4d4f7254297d9a3830 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 7 Dec 2008 03:03:16 -0800 Subject: [PATCH 49/52] GIT 1.6.0.5 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.0.5.txt | 43 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/Documentation/RelNotes-1.6.0.5.txt b/Documentation/RelNotes-1.6.0.5.txt index 1dc101c6a3..a08bb96738 100644 --- a/Documentation/RelNotes-1.6.0.5.txt +++ b/Documentation/RelNotes-1.6.0.5.txt @@ -4,40 +4,53 @@ GIT v1.6.0.5 Release Notes Fixes since v1.6.0.4 -------------------- -* 'git checkout' used to crash when your HEAD was pointing at a deleted +* "git checkout" used to crash when your HEAD was pointing at a deleted branch. -* 'git checkout' from an un-checked-out state did not allow switching out +* "git checkout" from an un-checked-out state did not allow switching out of the current branch. -* 'git diff' always allowed GIT_EXTERNAL_DIFF and --no-ext-diff was no-op for +* "git diff" always allowed GIT_EXTERNAL_DIFF and --no-ext-diff was no-op for the command. -* 'git fast-export' did not export all tags. +* Giving 3 or more tree-ish to "git diff" is supposed to show the combined + diff from second and subsequent trees to the first one, but the order was + screwed up. -* 'git ls-files --with-tree=' did not work with options other +* "git fast-export" did not export all tags. + +* "git ls-files --with-tree=" did not work with options other than -c, most notably with -m. -* 'git pack-objects' did not make its best effort to honor --max-pack-size +* "git pack-objects" did not make its best effort to honor --max-pack-size option when a single first object already busted the given limit and placed many objects in a single pack. -* 'git-p4' fast import frontend was too eager to trigger its keyword expansion +* "git-p4" fast import frontend was too eager to trigger its keyword expansion logic, even on a keyword-looking string that does not have closing '$' on the same line. -* 'git push $there' when the remote $there is defined in $GIT_DIR/branches/$there +* "git push $there" when the remote $there is defined in $GIT_DIR/branches/$there behaves more like what cg-push from Cogito used to work. -* 'git tag' did not complain when given mutually incompatible set of options. +* when giving up resolving a conflicted merge, "git reset --hard" failed + to remove new paths from the working tree. -* 'make check' cannot be run without sparse; people may have meant to say - 'make test' instead, so suggest that. +* "git tag" did not complain when given mutually incompatible set of options. + +* The message constructed in the internal editor was discarded when "git + tag -s" failed to sign the message, which was often caused by the user + not configuring GPG correctly. + +* "make check" cannot be run without sparse; people may have meant to say + "make test" instead, so suggest that. + +* Internal diff machinery had a corner case performance bug that choked on + a large file with many repeated contents. + +* "git repack" used to grab objects out of packs marked with .keep + into a new pack. * Many unsafe call to sprintf() style varargs functions are corrected. * Also contains quite a few documentation updates. - --- -O=v1.6.0.4-39-g27f6496 - From 0516cc5cc6ccb3b998ea5613ab178407c31339e3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 7 Dec 2008 15:06:38 -0800 Subject: [PATCH 50/52] Update draft release notes for 1.6.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A handful of fixes have been backmerged to 'maint' and are now contained in 1.6.0.X series as the result, so drop them from this document. Also contains typofix and duplicate removal pointed out by Bjørn Lindeijer and Jakub Narebski. Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.1.txt | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/Documentation/RelNotes-1.6.1.txt b/Documentation/RelNotes-1.6.1.txt index 9f5c0b5584..0405309743 100644 --- a/Documentation/RelNotes-1.6.1.txt +++ b/Documentation/RelNotes-1.6.1.txt @@ -70,7 +70,7 @@ on. subsequent "git diff" will show a diff as if they are creation events. * "git add" gained a built-in synonym for people who want to say "stage - changes" instead of "add contents the the staging area" which amounts + changes" instead of "add contents to the staging area" which amounts to the same thing. * "git apply" learned --include=paths option, similar to the existing @@ -135,16 +135,10 @@ on. cannot produce a patch that can be applied, so this is disabled in format-patch among other things). -* "git diff" hunk header pattern for ObjC has been added. - * "--cached" option to "git diff has an easier to remember synonym "--staged", to ask "what is the difference between the given commit and the contents staged in the index?" -* a "textconv" filter that makes binary files textual form for human - consumption can be specified as an attribute for paths; "git diff" - learnt to make use of it. - * "git for-each-ref" learned "refname:short" token that gives an unambiguously abbreviated refname. @@ -197,9 +191,6 @@ on. * "git remote show $remote" lists remote branches one-per-line now. -* when giving up resolving a conflicted merge, "git reset --hard" failed - to remove new paths from the working tree. [cherry-pick to 'maint'?] - * "git send-email" can be given revision range instead of files and maildirs on the command line, and automatically runs format-patch to generate patches for the given revision range. @@ -251,16 +242,8 @@ release, unless otherwise noted. but we dropped support for such a use case long time ago. This has been resurrected. -* Giving 3 or more tree-ish to "git diff" is supposed to show the combined - diff from second and subsequent trees to the first one. b75271d ("git - diff {3,}": do not reverse order of arguments, 2008-10-10) needs - to be cherry-picked to 'maint'. - * "git filter-branch" failed to rewrite a tag name with slashes in it. -* "git repack" used to grab objects out of packs marked with .keep - into a new pack (fix scheduled to be further downmerged to maint). - * "git rm --cached" used to allow an empty blob that was added earlier to be removed without --force, even when the file in the work tree has since been modified. @@ -272,10 +255,6 @@ release, unless otherwise noted. timestamp part, exposing internal implementation detail. Also these did not work with --fixed-strings match at all. -* Internal diff machinery had a corner case performance bug that choked on a - large file with many repeated contents (fix scheduled to be further cherry- - picked to maint). - * "gitweb" did not mark non-ASCII characters imported from external HTML fragments correctly. From 0e32126f04f6ad64826d4c145f2a1a9685e0910d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 7 Dec 2008 17:30:35 -0800 Subject: [PATCH 51/52] Revert "git-stash: use git rev-parse -q" This reverts commit 757c7f60a78004fc3d0ea62f44320d54ef430c10 as an unnecessary error message to pop up when the last stash entry is dropped. It simply is not worth the aggravation. --- git-stash.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/git-stash.sh b/git-stash.sh index c0532e8751..b9ace99704 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -30,7 +30,7 @@ clear_stash () { then die "git stash clear with parameters is unimplemented" fi - if current=$(git rev-parse -q --verify $ref_stash) + if current=$(git rev-parse --verify $ref_stash 2>/dev/null) then git update-ref -d $ref_stash $current fi @@ -129,7 +129,7 @@ save_stash () { } have_stash () { - git rev-parse -q --verify $ref_stash >/dev/null + git rev-parse --verify $ref_stash >/dev/null 2>&1 } list_stash () { @@ -229,16 +229,16 @@ drop_stash () { fi # Verify supplied argument looks like a stash entry s=$(git rev-parse --verify "$@") && - git rev-parse -q --verify "$s:" > /dev/null && - git rev-parse -q --verify "$s^1:" > /dev/null && - git rev-parse -q --verify "$s^2:" > /dev/null || + git rev-parse --verify "$s:" > /dev/null 2>&1 && + git rev-parse --verify "$s^1:" > /dev/null 2>&1 && + git rev-parse --verify "$s^2:" > /dev/null 2>&1 || die "$*: not a valid stashed state" git reflog delete --updateref --rewrite "$@" && echo "Dropped $* ($s)" || die "$*: Could not drop stash entry" # clear_stash if we just dropped the last stash entry - git rev-parse -q --verify "$ref_stash@{0}" > /dev/null || clear_stash + git rev-parse --verify "$ref_stash@{0}" > /dev/null 2>&1 || clear_stash } apply_to_branch () { From f371d3ea3ca7933df787230f2eb9b67901bde9d3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 7 Dec 2008 17:34:14 -0800 Subject: [PATCH 52/52] Point "stale" 1.6.0.5 documentation from the main git documentation page Signed-off-by: Junio C Hamano --- Documentation/git.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 7e0a041436..585af7a0d0 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ 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.0.4/git.html[documentation for release 1.6.0.4] +* link:v1.6.0.5/git.html[documentation for release 1.6.0.5] * release notes for + link:RelNotes-1.6.0.5.txt[1.6.0.5], link:RelNotes-1.6.0.4.txt[1.6.0.4], link:RelNotes-1.6.0.3.txt[1.6.0.3], link:RelNotes-1.6.0.2.txt[1.6.0.2],