From 108da0db1277fc2f4820d0a47c02b2c63111f7a5 Mon Sep 17 00:00:00 2001 From: Jens Lehmann Date: Sat, 10 Jul 2010 00:18:38 +0200 Subject: [PATCH 1/7] git add: Add the "--ignore-missing" option for the dry run Sometimes it is useful to know if a file or directory will be ignored before it is added to the work tree. An example is "git submodule add", where it would be really nice to be able to fail with an appropriate error message before the submodule is cloned and checked out. Signed-off-by: Jens Lehmann Signed-off-by: Junio C Hamano --- Documentation/git-add.txt | 9 ++++++++- builtin/add.c | 16 ++++++++++++---- dir.c | 2 +- dir.h | 1 + t/t3700-add.sh | 25 +++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 74741a42f4..bfea2c2d62 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -57,7 +57,8 @@ OPTIONS -n:: --dry-run:: - Don't actually add the file(s), just show if they exist. + Don't actually add the file(s), just show if they exist and/or will + be ignored. -v:: --verbose:: @@ -131,6 +132,12 @@ subdirectories. them, do not abort the operation, but continue adding the others. The command shall still exit with non-zero status. +--ignore-missing:: + This option can only be used together with --dry-run. By using + this option the user can check if any of the given files would + be ignored, no matter if they are already present in the work + tree or not. + \--:: This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken diff --git a/builtin/add.c b/builtin/add.c index 17149cfeed..56a4e0af6b 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -310,7 +310,7 @@ static const char ignore_error[] = "The following paths are ignored by one of your .gitignore files:\n"; static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0; -static int ignore_add_errors, addremove, intent_to_add; +static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0; static struct option builtin_add_options[] = { OPT__DRY_RUN(&show_only), @@ -325,6 +325,7 @@ static struct option builtin_add_options[] = { OPT_BOOLEAN('A', "all", &addremove, "add all, noticing removal of tracked files"), OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"), OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, "just skip files which cannot be added because of errors"), + OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, "check if - even missing - files are ignored in dry run"), OPT_END(), }; @@ -385,6 +386,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (addremove && take_worktree_changes) die("-A and -u are mutually incompatible"); + if (!show_only && ignore_missing) + die("Option --ignore-missing can only be used together with --dry-run"); if ((addremove || take_worktree_changes) && !argc) { static const char *here[2] = { ".", NULL }; argc = 1; @@ -441,9 +444,14 @@ int cmd_add(int argc, const char **argv, const char *prefix) seen = find_used_pathspec(pathspec); for (i = 0; pathspec[i]; i++) { if (!seen[i] && pathspec[i][0] - && !file_exists(pathspec[i])) - die("pathspec '%s' did not match any files", - pathspec[i]); + && !file_exists(pathspec[i])) { + if (ignore_missing) { + if (excluded(&dir, pathspec[i], DT_UNKNOWN)) + dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); + } else + die("pathspec '%s' did not match any files", + pathspec[i]); + } } free(seen); } diff --git a/dir.c b/dir.c index 151ea670d9..133f472a1e 100644 --- a/dir.c +++ b/dir.c @@ -453,7 +453,7 @@ static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna return dir->entries[dir->nr++] = dir_entry_new(pathname, len); } -static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len) +struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len) { if (!cache_name_is_other(pathname, len)) return NULL; diff --git a/dir.h b/dir.h index 3bead5f0e2..278d84cdf7 100644 --- a/dir.h +++ b/dir.h @@ -72,6 +72,7 @@ extern int read_directory(struct dir_struct *, const char *path, int len, const extern int excluded_from_list(const char *pathname, int pathlen, const char *basename, int *dtype, struct exclude_list *el); extern int excluded(struct dir_struct *, const char *, int *); +struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len); extern int add_excludes_from_file_to_list(const char *fname, const char *base, int baselen, char **buf_p, struct exclude_list *which, int check_index); extern void add_excludes_from_file(struct dir_struct *, const char *fname); diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 6f031af9f3..47fbf5362f 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -260,4 +260,29 @@ test_expect_success '"add non-existent" should fail' ' ! (git ls-files | grep "non-existent") ' +test_expect_success 'git add --dry-run of existing changed file' " + echo new >>track-this && + git add --dry-run track-this >actual 2>&1 && + echo \"add 'track-this'\" | test_cmp - actual +" + +test_expect_success 'git add --dry-run of non-existing file' " + echo ignored-file >>.gitignore && + ! (git add --dry-run track-this ignored-file >actual 2>&1) && + echo \"fatal: pathspec 'ignored-file' did not match any files\" | test_cmp - actual +" + +cat >expect <actual 2>&1) && + test_cmp expect actual +' + test_done From 8ac3a66702c43386eb580b7a1a8b1a31cd675327 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Sun, 18 Jul 2010 16:17:49 +0400 Subject: [PATCH 2/7] git-svn: write memoized data explicitly to avoid Storable bug Apparently using the Storable module during global destruction is unsafe - there is a bug which can cause segmentation faults: http://rt.cpan.org/Public/Bug/Display.html?id=36087 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=482355 The persistent memoization support introduced in commit 8bff7c538 relied on global destruction to write cached data, which was leading to segfaults in some Perl configurations. Calling Memoize::unmemoize in the END block forces the cache writeout to be performed earlier, thus avoiding the bug. Signed-off-by: Sergey Vlasov Acked-by: Eric Wong --- git-svn.perl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/git-svn.perl b/git-svn.perl index 19d6848d0e..c4163584a9 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -3169,6 +3169,22 @@ sub has_no_changes { LIST_CACHE => 'FAULT', ; } + + sub unmemoize_svn_mergeinfo_functions { + return if not $memoized; + $memoized = 0; + + Memoize::unmemoize 'lookup_svn_merge'; + Memoize::unmemoize 'check_cherry_pick'; + Memoize::unmemoize 'has_no_changes'; + } +} + +END { + # Force cache writeout explicitly instead of waiting for + # global destruction to avoid segfault in Storable: + # http://rt.cpan.org/Public/Bug/Display.html?id=36087 + unmemoize_svn_mergeinfo_functions(); } sub parents_exclude { From d1cc4621eda62222fbc929a7f65c89b6be678c2e Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sat, 17 Jul 2010 18:46:48 -0700 Subject: [PATCH 3/7] Documentation: Explain git-mergetool's use of temporary files 'git mergetool' creates '*.orig' backup files in its default configuration. Mention this in its documentation. Signed-off-by: David Aguilar Signed-off-by: Junio C Hamano --- Documentation/git-mergetool.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index 55735faf7b..e4ed016146 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -72,6 +72,16 @@ success of the resolution after the custom tool has exited. This is the default behaviour; the option is provided to override any configuration settings. +TEMPORARY FILES +--------------- +`git mergetool` creates `*.orig` backup files while resolving merges. +These are safe to remove once a file has been merged and its +`git mergetool` session has completed. + +Setting the `mergetool.keepBackup` configuration variable to `false` +causes `git mergetool` to automatically remove the backup as files +are successfully merged. + Author ------ Written by Theodore Y Ts'o From d27b876b284b8fb82db971bc7cea8c9782614ab2 Mon Sep 17 00:00:00 2001 From: Jens Lehmann Date: Sat, 17 Jul 2010 17:11:43 +0200 Subject: [PATCH 4/7] git submodule add: Require the new --force option to add ignored paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make the behavior of "git submodule add" more consistent with "git add" ignored submodule paths should not be silently added when they match an entry in a .gitignore file. To be able to override that default behavior in the same way as we can do that for "git add", the new option "--force" is introduced. Signed-off-by: Jens Lehmann Acked-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 7 ++++++- git-submodule.sh | 16 ++++++++++++++-- t/t7400-submodule-basic.sh | 27 +++++++++++++++------------ 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 76a832a3ac..617069fb04 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git submodule' [--quiet] add [-b branch] +'git submodule' [--quiet] add [-b branch] [-f|--force] [--reference ] [--] [] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] @@ -187,6 +187,11 @@ OPTIONS --branch:: Branch of repository to add as submodule. +-f:: +--force:: + This option is only valid for the add command. + Allow adding an otherwise ignored submodule path. + --cached:: This option is only valid for status and summary commands. These commands typically use the commit found in the submodule HEAD, but diff --git a/git-submodule.sh b/git-submodule.sh index ad2417d1b0..170186f494 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,7 @@ # Copyright (c) 2007 Lars Hjemli dashless=$(basename "$0" | sed -e 's/-/ /') -USAGE="[--quiet] add [-b branch] [--reference ] [--] [] +USAGE="[--quiet] add [-b branch] [-f|--force] [--reference ] [--] [] or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] or: $dashless [--quiet] init [--] [...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] @@ -19,6 +19,7 @@ require_work_tree command= branch= +force= reference= cached= recursive= @@ -133,6 +134,9 @@ cmd_add() branch=$2 shift ;; + -f | --force) + force=$1 + ;; -q|--quiet) GIT_QUIET=1 ;; @@ -201,6 +205,14 @@ cmd_add() git ls-files --error-unmatch "$path" > /dev/null 2>&1 && die "'$path' already exists in the index" + if test -z "$force" && ! git add --dry-run --ignore-missing "$path" > /dev/null 2>&1 + then + echo >&2 "The following path is ignored by one of your .gitignore files:" && + echo >&2 $path && + echo >&2 "Use -f if you really want to add it." + exit 1 + fi + # perhaps the path exists and is already a git repo, else clone it if test -e "$path" then @@ -234,7 +246,7 @@ cmd_add() ) || die "Unable to checkout submodule '$path'" fi - git add --force "$path" || + git add $force "$path" || die "Failed to add submodule '$path'" git config -f .gitmodules submodule."$path".path "$path" && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index d9f2785993..9bda970584 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -86,25 +86,28 @@ test_expect_success 'submodule add' ' test_cmp empty untracked ' -test_expect_success 'submodule add to .gitignored path' ' - echo "refs/heads/master" >expect && - >empty && - +test_expect_success 'submodule add to .gitignored path fails' ' ( cd addtest-ignore && + cat <<-\EOF >expect && + The following path is ignored by one of your .gitignore files: + submod + Use -f if you really want to add it. + EOF # Does not use test_commit due to the ignore echo "*" > .gitignore && git add --force .gitignore && git commit -m"Ignore everything" && - git submodule add "$submodurl" submod && - git submodule init - ) && + ! git submodule add "$submodurl" submod >actual 2>&1 && + test_cmp expect actual + ) +' - rm -f heads head untracked && - inspect addtest/submod ../.. && - test_cmp expect heads && - test_cmp expect head && - test_cmp empty untracked +test_expect_success 'submodule add to .gitignored path with --force' ' + ( + cd addtest-ignore && + git submodule add --force "$submodurl" submod + ) ' test_expect_success 'submodule add --branch' ' From 1f74574ba2d34fc9735e8113ed95def6accb6411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Sat, 17 Jul 2010 15:53:45 +0000 Subject: [PATCH 5/7] git submodule add: Remove old docs about implicit -f MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git submodule add no longer implicitly adds with --force. Remove references to the old functionality in the documentation. Signed-off-by: Ævar Arnfjörð Bjarmason Acked-by: Jens Lehmann Signed-off-by: Junio C Hamano --- Documentation/git-submodule.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 617069fb04..1ed331c599 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -95,10 +95,6 @@ is the superproject and submodule repositories will be kept together in the same relative location, and only the superproject's URL needs to be provided: git-submodule will correctly locate the submodule using the relative URL in .gitmodules. -+ -The submodule will be added with "git add --force ". I.e. git -doesn't care if the new path is in a `gitignore`. Your invocation of -"git submodule add" is considered enough to override it. status:: Show the status of the submodules. This will print the SHA-1 of the From f0e5a4b7f3db2d4e1ded9683817d1d1d3a2a220f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=86var=20Arnfj=C3=B6r=C3=B0=20Bjarmason?= Date: Sat, 17 Jul 2010 15:33:15 +0000 Subject: [PATCH 6/7] git add: Add --ignore-missing to SYNOPSIS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the git add options were listed in the synopsis until the --ignore-missing option was added. Change that so that the git add documentation now has the complete listing. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- Documentation/git-add.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index bfea2c2d62..e22a62f065 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -10,7 +10,8 @@ SYNOPSIS [verse] 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N] - [--refresh] [--ignore-errors] [--] [...] + [--refresh] [--ignore-errors] [--ignore-missing] [--] + [...] DESCRIPTION ----------- From c173dad58787a7f11a526dbcdaa5a2fe9ff1c87f Mon Sep 17 00:00:00 2001 From: Ralf Thielow Date: Mon, 19 Jul 2010 18:26:12 +0200 Subject: [PATCH 7/7] update-server-info: Shorten read_pack_info_file() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The correct responses to a D and a T line in .git/objects/info/packs are the same, so combine their case arms. In both cases we already ‘goto’ out of the switch so while at it, remove a redundant ‘break’ to avoid yet another line of code. Signed-off-by: Ralf Thielow Reviewed-by: Jonathan Nieder gmail.com> Signed-off-by: Junio C Hamano --- server-info.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/server-info.c b/server-info.c index 4098ca2b5c..9ec744e9f2 100644 --- a/server-info.c +++ b/server-info.c @@ -113,11 +113,8 @@ static int read_pack_info_file(const char *infofile) goto out_stale; break; case 'D': /* we used to emit D but that was misguided. */ - goto out_stale; - break; case 'T': /* we used to emit T but nobody uses it. */ goto out_stale; - break; default: error("unrecognized: %s", line); break;