From ae299be0e5e610027e6492d48d70c1cbb0e9edd8 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 19 May 2008 23:48:54 -0700 Subject: [PATCH 01/93] Implement normalize_absolute_path normalize_absolute_path removes several oddities form absolute paths, giving nice clean paths like "/dir/sub1/sub2". Also add a test case for this utility, based on a new test program (in the style of test-sha1). Signed-off-by: David Reiss Signed-off-by: Junio C Hamano --- .gitignore | 1 + Makefile | 2 +- cache.h | 1 + path.c | 53 +++++++++++++++++++++++++++++++++++++++++++ t/t0060-path-utils.sh | 40 ++++++++++++++++++++++++++++++++ test-path-utils.c | 13 +++++++++++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100755 t/t0060-path-utils.sh create mode 100644 test-path-utils.c diff --git a/.gitignore b/.gitignore index 4ff2fec278..c54c473e94 100644 --- a/.gitignore +++ b/.gitignore @@ -150,6 +150,7 @@ test-dump-cache-tree test-genrandom test-match-trees test-parse-options +test-path-utils test-sha1 common-cmds.h *.tar.gz diff --git a/Makefile b/Makefile index a2de075799..ada85686ea 100644 --- a/Makefile +++ b/Makefile @@ -1186,7 +1186,7 @@ endif ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X +TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X test-path-utils$X all:: $(TEST_PROGRAMS) diff --git a/cache.h b/cache.h index 093f04cec0..88c390d9f1 100644 --- a/cache.h +++ b/cache.h @@ -514,6 +514,7 @@ static inline int is_absolute_path(const char *path) return path[0] == '/'; } const char *make_absolute_path(const char *path); +int normalize_absolute_path(char *buf, const char *path); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); diff --git a/path.c b/path.c index b7c24a2aac..7175a06ed8 100644 --- a/path.c +++ b/path.c @@ -357,3 +357,56 @@ const char *make_absolute_path(const char *path) return buf; } + +/* + * path = absolute path + * buf = buffer of at least max(2, strlen(path)+1) bytes + * It is okay if buf == path, but they should not overlap otherwise. + * + * Performs the following normalizations on path, storing the result in buf: + * - Removes trailing slashes. + * - Removes empty components. + * - Removes "." components. + * - Removes ".." components, and the components the precede them. + * "" and paths that contain only slashes are normalized to "/". + * Returns the length of the output. + * + * Note that this function is purely textual. It does not follow symlinks, + * verify the existence of the path, or make any system calls. + */ +int normalize_absolute_path(char *buf, const char *path) +{ + const char *comp_start = path, *comp_end = path; + char *dst = buf; + int comp_len; + assert(buf); + assert(path); + + while (*comp_start) { + assert(*comp_start == '/'); + while (*++comp_end && *comp_end != '/') + ; /* nothing */ + comp_len = comp_end - comp_start; + + if (!strncmp("/", comp_start, comp_len) || + !strncmp("/.", comp_start, comp_len)) + goto next; + + if (!strncmp("/..", comp_start, comp_len)) { + while (dst > buf && *--dst != '/') + ; /* nothing */ + goto next; + } + + memcpy(dst, comp_start, comp_len); + dst += comp_len; + next: + comp_start = comp_end; + } + + if (dst == buf) + *dst++ = '/'; + + *dst = '\0'; + return dst - buf; +} diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh new file mode 100755 index 0000000000..9076b3bd81 --- /dev/null +++ b/t/t0060-path-utils.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Copyright (c) 2008 David Reiss +# + +test_description='Test various path utilities' + +. ./test-lib.sh + +norm_abs() { + test_expect_success "normalize absolute" \ + "test \$(test-path-utils normalize_absolute_path '$1') = '$2'" +} + +norm_abs "" / +norm_abs / / +norm_abs // / +norm_abs /// / +norm_abs /. / +norm_abs /./ / +norm_abs /./.. / +norm_abs /../. / +norm_abs /./../.// / +norm_abs /dir/.. / +norm_abs /dir/sub/../.. / +norm_abs /dir /dir +norm_abs /dir// /dir +norm_abs /./dir /dir +norm_abs /dir/. /dir +norm_abs /dir///./ /dir +norm_abs /dir//sub/.. /dir +norm_abs /dir/sub/../ /dir +norm_abs //dir/sub/../. /dir +norm_abs /dir/s1/../s2/ /dir/s2 +norm_abs /d1/s1///s2/..//../s3/ /d1/s3 +norm_abs /d1/s1//../s2/../../d2 /d2 +norm_abs /d1/.../d2 /d1/.../d2 +norm_abs /d1/..././../d2 /d1/d2 + +test_done diff --git a/test-path-utils.c b/test-path-utils.c new file mode 100644 index 0000000000..1bd43216f6 --- /dev/null +++ b/test-path-utils.c @@ -0,0 +1,13 @@ +#include "cache.h" + +int main(int argc, char **argv) +{ + if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) { + char *buf = xmalloc(strlen(argv[2])+1); + int rv = normalize_absolute_path(buf, argv[2]); + assert(strlen(buf) == rv); + puts(buf); + } + + return 0; +} From d553e737897e8edbbc2092bf345fc58b2dae5251 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 19 May 2008 23:49:00 -0700 Subject: [PATCH 02/93] Fold test-absolute-path into test-path-utils Signed-off-by: David Reiss Signed-off-by: Junio C Hamano --- .gitignore | 1 - Makefile | 2 +- t/t0000-basic.sh | 8 ++++---- test-absolute-path.c | 11 ----------- test-path-utils.c | 8 ++++++++ 5 files changed, 13 insertions(+), 17 deletions(-) delete mode 100644 test-absolute-path.c diff --git a/.gitignore b/.gitignore index c54c473e94..31ea9f13ba 100644 --- a/.gitignore +++ b/.gitignore @@ -142,7 +142,6 @@ git-write-tree git-core-*/?* gitk-wish gitweb/gitweb.cgi -test-absolute-path test-chmtime test-date test-delta diff --git a/Makefile b/Makefile index ada85686ea..c1903b68a8 100644 --- a/Makefile +++ b/Makefile @@ -1186,7 +1186,7 @@ endif ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-absolute-path$X test-parse-options$X test-path-utils$X +TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X all:: $(TEST_PROGRAMS) diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 690f80ab27..d7cbc5c6da 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -301,14 +301,14 @@ test_expect_success 'absolute path works as expected' ' mkdir third && dir="$(cd .git; pwd -P)" && dir2=third/../second/other/.git && - test "$dir" = "$(test-absolute-path $dir2)" && + test "$dir" = "$(test-path-utils make_absolute_path $dir2)" && file="$dir"/index && - test "$file" = "$(test-absolute-path $dir2/index)" && + test "$file" = "$(test-path-utils make_absolute_path $dir2/index)" && basename=blub && - test "$dir/$basename" = "$(cd .git && test-absolute-path "$basename")" && + test "$dir/$basename" = "$(cd .git && test-path-utils make_absolute_path "$basename")" && ln -s ../first/file .git/syml && sym="$(cd first; pwd -P)"/file && - test "$sym" = "$(test-absolute-path "$dir2/syml")" + test "$sym" = "$(test-path-utils make_absolute_path "$dir2/syml")" ' test_expect_success 'very long name in the index handled sanely' ' diff --git a/test-absolute-path.c b/test-absolute-path.c deleted file mode 100644 index c959ea20d3..0000000000 --- a/test-absolute-path.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "cache.h" - -int main(int argc, char **argv) -{ - while (argc > 1) { - puts(make_absolute_path(argv[1])); - argc--; - argv++; - } - return 0; -} diff --git a/test-path-utils.c b/test-path-utils.c index 1bd43216f6..842b58018f 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -9,5 +9,13 @@ int main(int argc, char **argv) puts(buf); } + if (argc >= 2 && !strcmp(argv[1], "make_absolute_path")) { + while (argc > 2) { + puts(make_absolute_path(argv[2])); + argc--; + argv++; + } + } + return 0; } From 0454dd93bfb2334355ec62fff670d8c6cb3570a1 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 19 May 2008 23:49:26 -0700 Subject: [PATCH 03/93] Add support for GIT_CEILING_DIRECTORIES Make git recognize a new environment variable that prevents it from chdir'ing up into specified directories when looking for a GIT_DIR. Useful for avoiding slow network directories. For example, I use git in an environment where homedirs are automounted and "ls /home/nonexistent" takes about 9 seconds. Setting GIT_CEILING_DIRS="/home" allows "git help -a" (for bash completion) and "git symbolic-ref" (for my shell prompt) to run in a reasonable time. Signed-off-by: David Reiss Signed-off-by: Junio C Hamano --- Documentation/git.txt | 8 ++ cache.h | 2 + path.c | 43 +++++++++++ setup.c | 24 +++--- t/t0060-path-utils.sh | 47 ++++++++++++ t/t1504-ceiling-dirs.sh | 163 ++++++++++++++++++++++++++++++++++++++++ t/test-lib.sh | 1 + test-path-utils.c | 5 ++ 8 files changed, 282 insertions(+), 11 deletions(-) create mode 100755 t/t1504-ceiling-dirs.sh diff --git a/Documentation/git.txt b/Documentation/git.txt index adcd3e00b2..4ffe802371 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -415,6 +415,14 @@ git so take care if using Cogito etc. This can also be controlled by the '--work-tree' command line option and the core.worktree configuration variable. +'GIT_CEILING_DIRECTORIES':: + This should be a colon-separated list of absolute paths. + If set, it is a list of directories that git should not chdir + up into while looking for a repository directory. + It will not exclude the current working directory or + a GIT_DIR set on the command line or in the environment. + (Useful for excluding slow-loading network directories.) + git Commits ~~~~~~~~~~~ 'GIT_AUTHOR_NAME':: diff --git a/cache.h b/cache.h index 88c390d9f1..833f4cd982 100644 --- a/cache.h +++ b/cache.h @@ -300,6 +300,7 @@ static inline enum object_type object_type(unsigned int mode) #define CONFIG_ENVIRONMENT "GIT_CONFIG" #define CONFIG_LOCAL_ENVIRONMENT "GIT_CONFIG_LOCAL" #define EXEC_PATH_ENVIRONMENT "GIT_EXEC_PATH" +#define CEILING_DIRECTORIES_ENVIRONMENT "GIT_CEILING_DIRECTORIES" #define GITATTRIBUTES_FILE ".gitattributes" #define INFOATTRIBUTES_FILE "info/attributes" #define ATTRIBUTE_MACRO_PREFIX "[attr]" @@ -515,6 +516,7 @@ static inline int is_absolute_path(const char *path) } const char *make_absolute_path(const char *path); int normalize_absolute_path(char *buf, const char *path); +int longest_ancestor_length(const char *path, const char *prefix_list); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); diff --git a/path.c b/path.c index 7175a06ed8..0c4330486b 100644 --- a/path.c +++ b/path.c @@ -410,3 +410,46 @@ int normalize_absolute_path(char *buf, const char *path) *dst = '\0'; return dst - buf; } + +/* + * path = Canonical absolute path + * prefix_list = Colon-separated list of absolute paths + * + * Determines, for each path in parent_list, whether the "prefix" really + * is an ancestor directory of path. Returns the length of the longest + * ancestor directory, excluding any trailing slashes, or -1 if no prefix + * is an ancestor. (Note that this means 0 is returned if prefix_list is + * "/".) "/foo" is not considered an ancestor of "/foobar". Directories + * are not considered to be their own ancestors. path must be in a + * canonical form: empty components, or "." or ".." components are not + * allowed. prefix_list may be null, which is like "". + */ +int longest_ancestor_length(const char *path, const char *prefix_list) +{ + char buf[PATH_MAX+1]; + const char *ceil, *colon; + int len, max_len = -1; + + if (prefix_list == NULL || !strcmp(path, "/")) + return -1; + + for (colon = ceil = prefix_list; *colon; ceil = colon+1) { + for (colon = ceil; *colon && *colon != ':'; colon++); + len = colon - ceil; + if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) + continue; + strlcpy(buf, ceil, len+1); + len = normalize_absolute_path(buf, buf); + /* Strip "trailing slashes" from "/". */ + if (len == 1) + len = 0; + + if (!strncmp(path, buf, len) && + path[len] == '/' && + len > max_len) { + max_len = len; + } + } + + return max_len; +} diff --git a/setup.c b/setup.c index b8fd476395..c14b10636f 100644 --- a/setup.c +++ b/setup.c @@ -359,10 +359,11 @@ const char *read_gitfile_gently(const char *path) const char *setup_git_directory_gently(int *nongit_ok) { const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT); + const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT); static char cwd[PATH_MAX+1]; const char *gitdirenv; const char *gitfile_dir; - int len, offset; + int len, offset, ceil_offset; /* * Let's assume that we are in a git repository. @@ -414,6 +415,8 @@ const char *setup_git_directory_gently(int *nongit_ok) if (!getcwd(cwd, sizeof(cwd)-1)) die("Unable to read current working directory"); + ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs); + /* * Test in the following order (relative to the cwd): * - .git (file containing "gitdir: ") @@ -444,17 +447,16 @@ const char *setup_git_directory_gently(int *nongit_ok) return NULL; } chdir(".."); - do { - if (!offset) { - if (nongit_ok) { - if (chdir(cwd)) - die("Cannot come back to cwd"); - *nongit_ok = 1; - return NULL; - } - die("Not a git repository"); + while (--offset > ceil_offset && cwd[offset] != '/'); + if (offset <= ceil_offset) { + if (nongit_ok) { + if (chdir(cwd)) + die("Cannot come back to cwd"); + *nongit_ok = 1; + return NULL; } - } while (cwd[--offset] != '/'); + die("Not a git repository"); + } } inside_git_dir = 0; diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 9076b3bd81..6e7501f352 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -12,6 +12,11 @@ norm_abs() { "test \$(test-path-utils normalize_absolute_path '$1') = '$2'" } +ancestor() { + test_expect_success "longest ancestor" \ + "test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'" +} + norm_abs "" / norm_abs / / norm_abs // / @@ -37,4 +42,46 @@ norm_abs /d1/s1//../s2/../../d2 /d2 norm_abs /d1/.../d2 /d1/.../d2 norm_abs /d1/..././../d2 /d1/d2 +ancestor / "" -1 +ancestor / / -1 +ancestor /foo "" -1 +ancestor /foo : -1 +ancestor /foo ::. -1 +ancestor /foo ::..:: -1 +ancestor /foo / 0 +ancestor /foo /fo -1 +ancestor /foo /foo -1 +ancestor /foo /foo/ -1 +ancestor /foo /bar -1 +ancestor /foo /bar/ -1 +ancestor /foo /foo/bar -1 +ancestor /foo /foo:/bar/ -1 +ancestor /foo /foo/:/bar/ -1 +ancestor /foo /foo::/bar/ -1 +ancestor /foo /:/foo:/bar/ 0 +ancestor /foo /foo:/:/bar/ 0 +ancestor /foo /:/bar/:/foo 0 +ancestor /foo/bar "" -1 +ancestor /foo/bar / 0 +ancestor /foo/bar /fo -1 +ancestor /foo/bar foo -1 +ancestor /foo/bar /foo 4 +ancestor /foo/bar /foo/ 4 +ancestor /foo/bar /foo/ba -1 +ancestor /foo/bar /:/fo 0 +ancestor /foo/bar /foo:/foo/ba 4 +ancestor /foo/bar /bar -1 +ancestor /foo/bar /bar/ -1 +ancestor /foo/bar /fo: -1 +ancestor /foo/bar :/fo -1 +ancestor /foo/bar /foo:/bar/ 4 +ancestor /foo/bar /:/foo:/bar/ 4 +ancestor /foo/bar /foo:/:/bar/ 4 +ancestor /foo/bar /:/bar/:/fo 0 +ancestor /foo/bar /:/bar/ 0 +ancestor /foo/bar :://foo/. 4 +ancestor /foo/bar :://foo/.:: 4 +ancestor /foo/bar //foo/./::/bar 4 +ancestor /foo/bar ::/bar -1 + test_done diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh new file mode 100755 index 0000000000..91b704a3a4 --- /dev/null +++ b/t/t1504-ceiling-dirs.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +test_description='test GIT_CEILING_DIRECTORIES' +. ./test-lib.sh + +test_prefix() { + test_expect_success "$1" \ + "test '$2' = \"\$(git rev-parse --show-prefix)\"" +} + +test_fail() { + test_expect_code 128 "$1: prefix" \ + "git rev-parse --show-prefix" +} + +TRASH_ROOT="$(pwd)" +ROOT_PARENT=$(dirname "$TRASH_ROOT") + + +unset GIT_CEILING_DIRECTORIES +test_prefix no_ceil "" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix ceil_empty "" + +GIT_CEILING_DIRECTORIES="$ROOT_PARENT" +test_prefix ceil_at_parent "" + +GIT_CEILING_DIRECTORIES="$ROOT_PARENT/" +test_prefix ceil_at_parent_slash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_prefix ceil_at_trash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_prefix ceil_at_trash_slash "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +test_prefix ceil_at_sub "" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" +test_prefix ceil_at_sub_slash "" + + +mkdir -p sub/dir || exit 1 +cd sub/dir || exit 1 + +unset GIT_CEILING_DIRECTORIES +test_prefix subdir_no_ceil "sub/dir/" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix subdir_ceil_empty "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_fail subdir_ceil_at_trash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_fail subdir_ceil_at_trash_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +test_fail subdir_ceil_at_sub + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" +test_fail subdir_ceil_at_sub_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir" +test_prefix subdir_ceil_at_subdir "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir/" +test_prefix subdir_ceil_at_subdir_slash "sub/dir/" + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su" +test_prefix subdir_ceil_at_su "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/" +test_prefix subdir_ceil_at_su_slash "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di" +test_prefix subdir_ceil_at_sub_di "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/di" +test_prefix subdir_ceil_at_sub_di_slash "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi" +test_prefix subdir_ceil_at_subdi "sub/dir/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/subdi" +test_prefix subdir_ceil_at_subdi_slash "sub/dir/" + + +GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub" +test_fail second_of_two + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub:bar" +test_fail first_of_two + +GIT_CEILING_DIRECTORIES="foo:$TRASH_ROOT/sub:bar" +test_fail second_of_three + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub" +GIT_DIR=../../.git +export GIT_DIR +test_prefix git_dir_specified "" +unset GIT_DIR + + +cd ../.. || exit 1 +mkdir -p s/d || exit 1 +cd s/d || exit 1 + +unset GIT_CEILING_DIRECTORIES +test_prefix sd_no_ceil "s/d/" + +export GIT_CEILING_DIRECTORIES + +GIT_CEILING_DIRECTORIES="" +test_prefix sd_ceil_empty "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT" +test_fail sd_ceil_at_trash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/" +test_fail sd_ceil_at_trash_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s" +test_fail sd_ceil_at_s + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/" +test_fail sd_ceil_at_s_slash + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d" +test_prefix sd_ceil_at_sd "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/d/" +test_prefix sd_ceil_at_sd_slash "s/d/" + + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su" +test_prefix sd_ceil_at_su "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/su/" +test_prefix sd_ceil_at_su_slash "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di" +test_prefix sd_ceil_at_s_di "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/s/di" +test_prefix sd_ceil_at_s_di_slash "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi" +test_prefix sd_ceil_at_sdi "s/d/" + +GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sdi" +test_prefix sd_ceil_at_sdi_slash "s/d/" + + +test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index 5002fb04b5..c3a3167382 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -35,6 +35,7 @@ unset GIT_WORK_TREE unset GIT_EXTERNAL_DIFF unset GIT_INDEX_FILE unset GIT_OBJECT_DIRECTORY +unset GIT_CEILING_DIRECTORIES unset SHA1_FILE_DIRECTORIES unset SHA1_FILE_DIRECTORY GIT_MERGE_VERBOSITY=5 diff --git a/test-path-utils.c b/test-path-utils.c index 842b58018f..a0bcb0e210 100644 --- a/test-path-utils.c +++ b/test-path-utils.c @@ -17,5 +17,10 @@ int main(int argc, char **argv) } } + if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { + int len = longest_ancestor_length(argv[2], argv[3]); + printf("%d\n", len); + } + return 0; } From 450f437fb0fe276a6e946c281c768118e39dc9e7 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Mon, 19 May 2008 23:49:34 -0700 Subject: [PATCH 04/93] Eliminate an unnecessary chdir("..") In the case where setup_git_directory_gently fails, avoid the last chdir("..") by moving it after the ceil_offset check. Signed-off-by: David Reiss Signed-off-by: Junio C Hamano --- setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.c b/setup.c index c14b10636f..045ca20b32 100644 --- a/setup.c +++ b/setup.c @@ -446,7 +446,6 @@ const char *setup_git_directory_gently(int *nongit_ok) check_repository_format_gently(nongit_ok); return NULL; } - chdir(".."); while (--offset > ceil_offset && cwd[offset] != '/'); if (offset <= ceil_offset) { if (nongit_ok) { @@ -457,6 +456,7 @@ const char *setup_git_directory_gently(int *nongit_ok) } die("Not a git repository"); } + chdir(".."); } inside_git_dir = 0; From 8a965b8ee28bedc58641453e13d03f80180320dd Mon Sep 17 00:00:00 2001 From: Abhijit Menon-Sen Date: Fri, 13 Jun 2008 03:42:10 +0530 Subject: [PATCH 05/93] git-gui: Move on to the next filename after staging/unstaging a change Suppose the "Unstaged Changes" pane contains a list of files, and one of them is selected (i.e., that diff is currently being displayed). If one clicks on the icon to stage the change, git-gui clears the diff and one has to click on another filename to see the next diff in the list. This patch changes that behaviour. If one clicks on the icon to stage (or unstage) the file whose diff is being displayed, git-gui will move on to the next filename in the list and display that diff instead of a blank diff pane. If the selected file was at the end of the list, the diff pane will display the previous diff instead; if the selected file was the only one listed, the diff pane will become blank. If no diff is currently being displayed, this patch changes nothing. Signed-off-by: Abhijit Menon-Sen Signed-off-by: Shawn O. Pearce --- git-gui.sh | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index e6e88902f1..23d7dfec79 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1774,6 +1774,11 @@ proc do_commit {} { commit_tree } +proc next_diff {} { + global next_diff_p next_diff_w next_diff_i + show_diff $next_diff_p $next_diff_w $next_diff_i +} + proc toggle_or_diff {w x y} { global file_states file_lists current_diff_path ui_index ui_workdir global last_clicked selected_paths @@ -1793,11 +1798,31 @@ proc toggle_or_diff {w x y} { $ui_workdir tag remove in_sel 0.0 end if {$col == 0} { - if {$current_diff_path eq $path} { + set i [expr {$lno-1}] + set ll [expr {[llength $file_lists($w)]-1}] + + if {$i == $ll && $i == 0} { set after {reshow_diff;} } else { - set after {} + global next_diff_p next_diff_w next_diff_i + + if {$i < $ll} { + set i [expr {$i + 1}] + } else { + set i [expr {$i - 1}] + } + + set next_diff_i $i + set next_diff_w $w + set next_diff_p [lindex $file_lists($w) $i] + + if {$next_diff_p ne {} && $current_diff_path ne {}} { + set after {next_diff;} + } else { + set after {} + } } + if {$w eq $ui_index} { update_indexinfo \ "Unstaging [short_path $path] from commit" \ From cead78edef6a2f1339f699cd7d656b6834707b94 Mon Sep 17 00:00:00 2001 From: Richard Quirk Date: Fri, 20 Jun 2008 16:58:15 +0200 Subject: [PATCH 06/93] git-gui: Fix accidental staged state toggle when clicking top pixel row If a text widget is asked the index at x,y with y == 0 or y == 1 it will always return 1.0 as the nearest index, regardless of the x position. This means that clicking the top 2 pixels of the Unstaged/Staged Changes lists caused the state of the file there to be toggled. This patch checks that the pixel clicked is greater than 1, so there is less chance of accidentally staging or unstaging changes. Signed-off-by: Richard Quirk Signed-off-by: Shawn O. Pearce --- git-gui.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-gui.sh b/git-gui.sh index 23d7dfec79..980dc0b373 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1797,7 +1797,7 @@ proc toggle_or_diff {w x y} { $ui_index tag remove in_sel 0.0 end $ui_workdir tag remove in_sel 0.0 end - if {$col == 0} { + if {$col == 0 && $y > 1} { set i [expr {$lno-1}] set ll [expr {[llength $file_lists($w)]-1}] From 9022a495a3c407859560d4ac4a278c0d6ad58837 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 21 Jun 2008 23:28:58 -0700 Subject: [PATCH 07/93] rerere: rerere_created_at() and has_resolution() abstraction There were too many places in the code how an entry in the rerere database looks like, and the garbage_collect() function that iterates over subdirectories of the rr-cache directory was the worse offender. Introduce two helper functions, rerere_created_at() and has_resolution(), to abstract out the logic a bit better. Incidentally this fixes a small memory leak in garbage_collect() function. The path list to collect the entries to be pruned were defined to strdup the paths but the caller was feeding a path after doing an extra copy. Because the list does not have to be sorted by conflict signature hash, we use path_list_append() instead of path_list_insert(). While we are at it, make a conflicted hunk comparision in handle_file() a bit easier to read. Signed-off-by: Junio C Hamano --- builtin-rerere.c | 57 ++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/builtin-rerere.c b/builtin-rerere.c index 85222d9bc5..610b96a120 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -23,6 +23,18 @@ static const char *rr_path(const char *name, const char *file) return git_path("rr-cache/%s/%s", name, file); } +static time_t rerere_created_at(const char *name) +{ + struct stat st; + return stat(rr_path(name, "preimage"), &st) ? (time_t) 0 : st.st_mtime; +} + +static int has_resolution(const char *name) +{ + struct stat st; + return !stat(rr_path(name, "postimage"), &st); +} + static void read_rr(struct path_list *rr) { unsigned char sha1[20]; @@ -98,13 +110,10 @@ static int handle_file(const char *path, else if (!prefixcmp(buf, "=======")) hunk = 2; else if (!prefixcmp(buf, ">>>>>>> ")) { - int cmp = strbuf_cmp(&one, &two); - + if (strbuf_cmp(&one, &two) > 0) + strbuf_swap(&one, &two); hunk_no++; hunk = 0; - if (cmp > 0) { - strbuf_swap(&one, &two); - } if (out) { fputs("<<<<<<<\n", out); fwrite(one.buf, one.len, 1, out); @@ -201,33 +210,24 @@ static void unlink_rr_item(const char *name) static void garbage_collect(struct path_list *rr) { struct path_list to_remove = { NULL, 0, 0, 1 }; - char buf[1024]; DIR *dir; struct dirent *e; - int len, i, cutoff; + int i, cutoff; time_t now = time(NULL), then; - strlcpy(buf, git_path("rr-cache"), sizeof(buf)); - len = strlen(buf); - dir = opendir(buf); - strcpy(buf + len++, "/"); + dir = opendir(git_path("rr-cache")); while ((e = readdir(dir))) { const char *name = e->d_name; - struct stat st; - if (name[0] == '.' && (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0'))) + if (name[0] == '.' && + (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) continue; - i = snprintf(buf + len, sizeof(buf) - len, "%s", name); - strlcpy(buf + len + i, "/preimage", sizeof(buf) - len - i); - if (stat(buf, &st)) + then = rerere_created_at(name); + if (!then) continue; - then = st.st_mtime; - strlcpy(buf + len + i, "/postimage", sizeof(buf) - len - i); - cutoff = stat(buf, &st) ? cutoff_noresolve : cutoff_resolve; - if (then < now - cutoff * 86400) { - buf[len + i] = '\0'; - path_list_insert(xstrdup(name), &to_remove); - } + cutoff = (has_resolution(name) + ? cutoff_resolve : cutoff_noresolve); + if (then < now - cutoff * 86400) + path_list_append(name, &to_remove); } for (i = 0; i < to_remove.nr; i++) unlink_rr_item(to_remove.items[i].path); @@ -306,13 +306,11 @@ static int do_plain_rerere(struct path_list *rr, int fd) */ for (i = 0; i < rr->nr; i++) { - struct stat st; int ret; const char *path = rr->items[i].path; const char *name = (const char *)rr->items[i].util; - if (!stat(rr_path(name, "preimage"), &st) && - !stat(rr_path(name, "postimage"), &st)) { + if (has_resolution(name)) { if (!merge(name, path)) { fprintf(stderr, "Resolved '%s' using " "previous resolution.\n", path); @@ -410,11 +408,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix) return do_plain_rerere(&merge_rr, fd); else if (!strcmp(argv[1], "clear")) { for (i = 0; i < merge_rr.nr; i++) { - struct stat st; const char *name = (const char *)merge_rr.items[i].util; - if (!stat(git_path("rr-cache/%s", name), &st) && - S_ISDIR(st.st_mode) && - stat(rr_path(name, "postimage"), &st)) + if (!has_resolution(name)) unlink_rr_item(name); } unlink(merge_rr_path); From a1b32fdc3d1d05395f186bfa06e92174519dab8d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 22 Jun 2008 00:21:28 -0700 Subject: [PATCH 08/93] git-rerere: detect unparsable conflicts rerere did not detect the case where <<< === >>> markers did not match. Signed-off-by: Junio C Hamano --- builtin-rerere.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builtin-rerere.c b/builtin-rerere.c index 610b96a120..addc5c73df 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -144,6 +144,11 @@ static int handle_file(const char *path, fclose(out); if (sha1) SHA1_Final(sha1, &ctx); + if (hunk) { + if (output) + unlink(output); + return error("Could not parse conflict hunks in %s", path); + } return hunk_no; } From 51e0d0a67b8d31e92d52e15b577afb079359ec63 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 22 Jun 2008 00:27:46 -0700 Subject: [PATCH 09/93] rerere: remove dubious "tail_optimization" It is dubious if it is cheaper to shift entries repeatedly using memmove() to collect entries that needs to be written out in front of an array than simply marking the entries to be skipped. In addition, the label called this "tail optimization", but this obviously is not what people usually call with that name. Signed-off-by: Junio C Hamano --- builtin-rerere.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/builtin-rerere.c b/builtin-rerere.c index addc5c73df..0eec1f9373 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -66,8 +66,12 @@ static int write_rr(struct path_list *rr, int out_fd) { int i; for (i = 0; i < rr->nr; i++) { - const char *path = rr->items[i].path; - int length = strlen(path) + 1; + const char *path; + int length; + if (!rr->items[i].util) + continue; + path = rr->items[i].path; + length = strlen(path) + 1; if (write_in_full(out_fd, rr->items[i].util, 40) != 40 || write_in_full(out_fd, "\t", 1) != 1 || write_in_full(out_fd, path, length) != length) @@ -319,7 +323,7 @@ static int do_plain_rerere(struct path_list *rr, int fd) if (!merge(name, path)) { fprintf(stderr, "Resolved '%s' using " "previous resolution.\n", path); - goto tail_optimization; + goto mark_resolved; } } @@ -330,13 +334,8 @@ static int do_plain_rerere(struct path_list *rr, int fd) fprintf(stderr, "Recorded resolution for '%s'.\n", path); copy_file(rr_path(name, "postimage"), path, 0666); -tail_optimization: - if (i < rr->nr - 1) - memmove(rr->items + i, - rr->items + i + 1, - sizeof(rr->items[0]) * (rr->nr - i - 1)); - rr->nr--; - i--; + mark_resolved: + rr->items[i].util = NULL; } return write_rr(rr, fd); From 7f8365f894d60f240edd356f32e3c1bda994ed41 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 22 Jun 2008 02:03:26 -0700 Subject: [PATCH 10/93] t4200: fix rerere test The test used "diff-files -q" which is not about reporting if there is a difference at all. Instead, make sure that the path remains as conflicting in the index after rerere autoresolves it, as we will be adding rerere.autoupdate configuration with the next patch. --- t/t4200-rerere.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 85d7e3edcd..afb3e3d176 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -193,9 +193,9 @@ test_expect_success 'resolution was recorded properly' ' echo Bello > file3 && git add file3 && git commit -m version2 && - ! git merge fifth && - git diff-files -q && - test Cello = "$(cat file3)" + test_must_fail git merge fifth && + test Cello = "$(cat file3)" && + test 0 != $(git ls-files -u | wc -l) ' test_done From 121c813f8d6054dbee25c03301599c0f8d645d7f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 22 Jun 2008 02:04:31 -0700 Subject: [PATCH 11/93] rerere.autoupdate When this configuration is set, paths that are autoresolved by git-rerere are updated in the index as well. --- Documentation/config.txt | 5 +++++ builtin-rerere.c | 37 +++++++++++++++++++++++++++++++++++++ t/t4200-rerere.sh | 10 ++++++++++ 3 files changed, 52 insertions(+) diff --git a/Documentation/config.txt b/Documentation/config.txt index 5331b450ea..0c7cf618ed 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -650,6 +650,11 @@ gc.rerereunresolved:: kept for this many days when `git rerere gc` is run. The default is 15 days. See linkgit:git-rerere[1]. +rerere.autoupdate:: + When set to true, `git-rerere` updates the index with the + resulting contents after it cleanly resolves conflicts using + previously recorded resolution. Defaults to false. + rerere.enabled:: Activate recording of resolved conflicts, so that identical conflict hunks can be resolved automatically, should they diff --git a/builtin-rerere.c b/builtin-rerere.c index 0eec1f9373..839b26e8e0 100644 --- a/builtin-rerere.c +++ b/builtin-rerere.c @@ -16,6 +16,9 @@ static int cutoff_resolve = 60; /* if rerere_enabled == -1, fall back to detection of .git/rr-cache */ static int rerere_enabled = -1; +/* automatically update cleanly resolved paths to the index */ +static int rerere_autoupdate; + static char *merge_rr_path; static const char *rr_path(const char *name, const char *file) @@ -276,9 +279,36 @@ static int diff_two(const char *file1, const char *label1, return 0; } +static struct lock_file index_lock; + +static int update_paths(struct path_list *update) +{ + int i; + int fd = hold_locked_index(&index_lock, 0); + int status = 0; + + if (fd < 0) + return -1; + + for (i = 0; i < update->nr; i++) { + struct path_list_item *item = &update->items[i]; + if (add_file_to_cache(item->path, ADD_CACHE_IGNORE_ERRORS)) + status = -1; + } + + if (!status && active_cache_changed) { + if (write_cache(fd, active_cache, active_nr) || + commit_locked_index(&index_lock)) + die("Unable to write new index file"); + } else if (fd >= 0) + rollback_lock_file(&index_lock); + return status; +} + static int do_plain_rerere(struct path_list *rr, int fd) { struct path_list conflict = { NULL, 0, 0, 1 }; + struct path_list update = { NULL, 0, 0, 1 }; int i; find_conflict(&conflict); @@ -323,6 +353,8 @@ static int do_plain_rerere(struct path_list *rr, int fd) if (!merge(name, path)) { fprintf(stderr, "Resolved '%s' using " "previous resolution.\n", path); + if (rerere_autoupdate) + path_list_insert(path, &update); goto mark_resolved; } } @@ -338,6 +370,9 @@ static int do_plain_rerere(struct path_list *rr, int fd) rr->items[i].util = NULL; } + if (update.nr) + update_paths(&update); + return write_rr(rr, fd); } @@ -349,6 +384,8 @@ static int git_rerere_config(const char *var, const char *value, void *cb) cutoff_noresolve = git_config_int(var, value); else if (!strcmp(var, "rerere.enabled")) rerere_enabled = git_config_bool(var, value); + else if (!strcmp(var, "rerere.autoupdate")) + rerere_autoupdate = git_config_bool(var, value); else return git_default_config(var, value, cb); return 0; diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index afb3e3d176..a64727d5ad 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -193,9 +193,19 @@ test_expect_success 'resolution was recorded properly' ' echo Bello > file3 && git add file3 && git commit -m version2 && + git tag version2 && test_must_fail git merge fifth && test Cello = "$(cat file3)" && test 0 != $(git ls-files -u | wc -l) ' +test_expect_success 'rerere.autoupdate' ' + git config rerere.autoupdate true + git reset --hard && + git checkout version2 && + test_must_fail git merge fifth && + test 0 = $(git ls-files -u | wc -l) + +' + test_done From f531e463f0471ce41c51e19074a118482f36910f Mon Sep 17 00:00:00 2001 From: Abhijit Menon-Sen Date: Wed, 25 Jun 2008 16:06:50 +0530 Subject: [PATCH 12/93] git-gui: Don't select the wrong file if the last listed file is staged. Johannes Sixt noticed that if the last file in the list was staged, my earlier patch would display the diff for the penultimate file, but show the file _before_ that as being selected. This was due to my misunderstanding the lno argument to show_diff. This patch fixes the problem: lno is not decremented in the special case to handle the last item in the list (though we still need to use $lno-1 to find the right path for the next diff). Signed-off-by: Abhijit Menon-Sen Tested-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- git-gui.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 980dc0b373..1bbae15a50 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1806,14 +1806,16 @@ proc toggle_or_diff {w x y} { } else { global next_diff_p next_diff_w next_diff_i + set next_diff_w $w + if {$i < $ll} { set i [expr {$i + 1}] + set next_diff_i $i } else { + set next_diff_i $i set i [expr {$i - 1}] } - set next_diff_i $i - set next_diff_w $w set next_diff_p [lindex $file_lists($w) $i] if {$next_diff_p ne {} && $current_diff_path ne {}} { From 3cb22b8efe2cab60dc0ef5e265c414bd826d83ef Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 15 Jun 2008 23:48:46 -0700 Subject: [PATCH 13/93] Per-ref reflog expiry configuration In addition to gc.reflogexpireunreachable and gc.reflogexpire, this lets you set gc..reflogexpireunreachable and gc..reflogexpire variables. When "git reflog expire" expires reflog entry for $ref, the expiry timers are taken from the first that matches $ref (and if there isn't the global default value is used). For example, you could: [gc "refs/stash"] reflogexpire = never reflogexpireunreachable = never [gc "refs/remotes/*"] reflogexpire = 7 days reflogexpireunreachable = 3 days [gc] reflogexpire = 90 days reflogexpireunreachable = 30 days Signed-off-by: Junio C Hamano --- builtin-reflog.c | 145 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 19 deletions(-) diff --git a/builtin-reflog.c b/builtin-reflog.c index b151e24ff9..0711728908 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -269,7 +269,9 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, int status = 0; memset(&cb, 0, sizeof(cb)); - /* we take the lock for the ref itself to prevent it from + + /* + * we take the lock for the ref itself to prevent it from * getting updated. */ lock = lock_any_ref_for_update(ref, sha1, 0); @@ -331,21 +333,119 @@ static int collect_reflog(const char *ref, const unsigned char *sha1, int unused return 0; } +static struct reflog_expire_cfg { + struct reflog_expire_cfg *next; + unsigned long expire_total; + unsigned long expire_unreachable; + size_t len; + char pattern[FLEX_ARRAY]; +} *reflog_expire_cfg, **reflog_expire_cfg_tail; + +static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len) +{ + struct reflog_expire_cfg *ent; + + if (!reflog_expire_cfg_tail) + reflog_expire_cfg_tail = &reflog_expire_cfg; + + for (ent = reflog_expire_cfg; ent; ent = ent->next) + if (ent->len == len && + !memcmp(ent->pattern, pattern, len)) + return ent; + + ent = xcalloc(1, (sizeof(*ent) + len)); + memcpy(ent->pattern, pattern, len); + ent->len = len; + *reflog_expire_cfg_tail = ent; + reflog_expire_cfg_tail = &(ent->next); + return ent; +} + +static int parse_expire_cfg_value(const char *var, const char *value, unsigned long *expire) +{ + if (!value) + return config_error_nonbool(var); + if (!strcmp(value, "never") || !strcmp(value, "false")) { + *expire = 0; + return 0; + } + *expire = approxidate(value); + return 0; +} + +/* expiry timer slot */ +#define EXPIRE_TOTAL 01 +#define EXPIRE_UNREACH 02 + static int reflog_expire_config(const char *var, const char *value, void *cb) { - if (!strcmp(var, "gc.reflogexpire")) { - if (!value) - config_error_nonbool(var); - default_reflog_expire = approxidate(value); + const char *lastdot = strrchr(var, '.'); + unsigned long expire; + int slot; + struct reflog_expire_cfg *ent; + + if (!lastdot || prefixcmp(var, "gc.")) + return git_default_config(var, value, cb); + + if (!strcmp(lastdot, ".reflogexpire")) { + slot = EXPIRE_TOTAL; + if (parse_expire_cfg_value(var, value, &expire)) + return -1; + } else if (!strcmp(lastdot, ".reflogexpireunreachable")) { + slot = EXPIRE_UNREACH; + if (parse_expire_cfg_value(var, value, &expire)) + return -1; + } else + return git_default_config(var, value, cb); + + if (lastdot == var + 2) { + switch (slot) { + case EXPIRE_TOTAL: + default_reflog_expire = expire; + break; + case EXPIRE_UNREACH: + default_reflog_expire_unreachable = expire; + break; + } return 0; } - if (!strcmp(var, "gc.reflogexpireunreachable")) { - if (!value) - config_error_nonbool(var); - default_reflog_expire_unreachable = approxidate(value); - return 0; + + ent = find_cfg_ent(var + 3, lastdot - (var+3)); + if (!ent) + return -1; + switch (slot) { + case EXPIRE_TOTAL: + ent->expire_total = expire; + break; + case EXPIRE_UNREACH: + ent->expire_unreachable = expire; + break; } - return git_default_config(var, value, cb); + return 0; +} + +static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, const char *ref) +{ + struct reflog_expire_cfg *ent; + + if (slot == (EXPIRE_TOTAL|EXPIRE_UNREACH)) + return; /* both given explicitly -- nothing to tweak */ + + for (ent = reflog_expire_cfg; ent; ent = ent->next) { + if (!fnmatch(ent->pattern, ref, 0)) { + if (!(slot & EXPIRE_TOTAL)) + cb->expire_total = ent->expire_total; + if (!(slot & EXPIRE_UNREACH)) + cb->expire_unreachable = ent->expire_unreachable; + return; + } + } + + /* Nothing matched -- use the default value */ + if (!(slot & EXPIRE_TOTAL)) + cb->expire_total = default_reflog_expire; + if (!(slot & EXPIRE_UNREACH)) + cb->expire_unreachable = default_reflog_expire_unreachable; } static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) @@ -353,6 +453,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) struct cmd_reflog_expire_cb cb; unsigned long now = time(NULL); int i, status, do_all; + int explicit_expiry = 0; git_config(reflog_expire_config, NULL); @@ -367,20 +468,18 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) cb.expire_total = default_reflog_expire; cb.expire_unreachable = default_reflog_expire_unreachable; - /* - * We can trust the commits and objects reachable from refs - * even in older repository. We cannot trust what's reachable - * from reflog if the repository was pruned with older git. - */ - for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n")) cb.dry_run = 1; - else if (!prefixcmp(arg, "--expire=")) + else if (!prefixcmp(arg, "--expire=")) { cb.expire_total = approxidate(arg + 9); - else if (!prefixcmp(arg, "--expire-unreachable=")) + explicit_expiry |= EXPIRE_TOTAL; + } + else if (!prefixcmp(arg, "--expire-unreachable=")) { cb.expire_unreachable = approxidate(arg + 21); + explicit_expiry |= EXPIRE_UNREACH; + } else if (!strcmp(arg, "--stale-fix")) cb.stalefix = 1; else if (!strcmp(arg, "--rewrite")) @@ -400,6 +499,12 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) else break; } + + /* + * We can trust the commits and objects reachable from refs + * even in older repository. We cannot trust what's reachable + * from reflog if the repository was pruned with older git. + */ if (cb.stalefix) { init_revisions(&cb.revs, prefix); if (cb.verbose) @@ -417,6 +522,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) for_each_reflog(collect_reflog, &collected); for (i = 0; i < collected.nr; i++) { struct collected_reflog *e = collected.e[i]; + set_reflog_expiry_param(&cb, explicit_expiry, e->reflog); status |= expire_reflog(e->reflog, e->sha1, 0, &cb); free(e); } @@ -430,6 +536,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) status |= error("%s points nowhere!", ref); continue; } + set_reflog_expiry_param(&cb, explicit_expiry, ref); status |= expire_reflog(ref, sha1, 0, &cb); } return status; From 60bce2bb8b3cd5ca56f8156cbca16abee151d817 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 28 Jun 2008 22:24:49 -0700 Subject: [PATCH 14/93] Make default expiration period of reflog used for stash infinite This makes the default expiration period for the reflog that implements stash infinite. The original behaviour to autoexpire old stashes can be restored by using the gc.refs/stash.{reflogexpire,reflogexpireunreachable} configration variables introduced by the previous commit. Signed-off-by: Junio C Hamano --- builtin-reflog.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/builtin-reflog.c b/builtin-reflog.c index 0711728908..125d455b97 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -441,6 +441,17 @@ static void set_reflog_expiry_param(struct cmd_reflog_expire_cb *cb, int slot, c } } + /* + * If unconfigured, make stash never expire + */ + if (!strcmp(ref, "refs/stash")) { + if (!(slot & EXPIRE_TOTAL)) + cb->expire_total = 0; + if (!(slot & EXPIRE_UNREACH)) + cb->expire_unreachable = 0; + return; + } + /* Nothing matched -- use the default value */ if (!(slot & EXPIRE_TOTAL)) cb->expire_total = default_reflog_expire; From be612c2318e87a9d32a385c7684459e9e0cd6227 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Mon, 30 Jun 2008 19:50:44 +0100 Subject: [PATCH 15/93] Add another fast-import example, this time for .zip files Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- contrib/fast-import/import-zips.py | 72 ++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 contrib/fast-import/import-zips.py diff --git a/contrib/fast-import/import-zips.py b/contrib/fast-import/import-zips.py new file mode 100755 index 0000000000..c674fa2d1b --- /dev/null +++ b/contrib/fast-import/import-zips.py @@ -0,0 +1,72 @@ +#!/usr/bin/python + +## zip archive frontend for git-fast-import +## +## For example: +## +## mkdir project; cd project; git init +## python import-zips.py *.zip +## git log --stat import-zips + +from os import popen, path +from sys import argv, exit +from time import mktime +from zipfile import ZipFile + +if len(argv) < 2: + print 'Usage:', argv[0], '...' + exit(1) + +branch_ref = 'refs/heads/import-zips' +committer_name = 'Z Ip Creator' +committer_email = 'zip@example.com' + +fast_import = popen('git fast-import --quiet', 'w') +def printlines(list): + for str in list: + fast_import.write(str + "\n") + +for zipfile in argv[1:]: + commit_time = 0 + next_mark = 1 + common_prefix = None + mark = dict() + + zip = ZipFile(zipfile, 'r') + for name in zip.namelist(): + if name.endswith('/'): + continue + info = zip.getinfo(name) + + if commit_time < info.date_time: + commit_time = info.date_time + if common_prefix == None: + common_prefix = name[:name.rfind('/') + 1] + else: + while not name.startswith(common_prefix): + common_prefix = name[:name.rfind('/') + 1] + + mark[name] = ':' + str(next_mark) + next_mark += 1 + + printlines(('blob', 'mark ' + mark[name], \ + 'data ' + str(info.file_size))) + fast_import.write(zip.read(name) + "\n") + + committer = committer_name + ' <' + committer_email + '> %d +0000' % \ + mktime(commit_time + (0, 0, 0)) + + printlines(('commit ' + branch_ref, 'committer ' + committer, \ + 'data < Date: Mon, 30 Jun 2008 03:37:47 -0400 Subject: [PATCH 16/93] Only use GIT_CONFIG in "git config", not other programs For everything other than using "git config" to read or write a git-style config file that isn't the current repo's config file, GIT_CONFIG was actively detrimental. Rather than argue over which programs are important enough to have work anyway, just fix all of them at the root. Also removes GIT_LOCAL_CONFIG, which would only be useful for programs that do want to use global git-specific config, but not the repo's own git-specific config, and want to use some other, presumably git-specific config. Despite being documented, I can't find any sign that it was ever used. Signed-off-by: Daniel Barkalow Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.6.0.txt | 5 ++++ Documentation/git-config.txt | 9 ------ builtin-config.c | 15 +++++----- cache.h | 2 +- config.c | 47 ++++++++++++++------------------ 5 files changed, 33 insertions(+), 45 deletions(-) diff --git a/Documentation/RelNotes-1.6.0.txt b/Documentation/RelNotes-1.6.0.txt index 03e3a59ff5..d37aa46a28 100644 --- a/Documentation/RelNotes-1.6.0.txt +++ b/Documentation/RelNotes-1.6.0.txt @@ -21,6 +21,11 @@ scripts to use "git xyzzy" form, as we will stop installing Source changes needed for porting to MinGW environment are now all in the main git.git codebase. +GIT_CONFIG, which was only documented as affecting "git config", but +actually affected all git commands, now only affects "git config". +GIT_LOCAL_CONFIG, also only documented as affecting "git config" and +not different from GIT_CONFIG in a useful way, is removed. + Updates since v1.5.6 -------------------- diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index c90421ee7f..30c8432267 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -191,11 +191,6 @@ variables. The '--global' and the '--system' options will limit the file used to the global or system-wide file respectively. The GIT_CONFIG environment variable has a similar effect, but you can specify any filename you want. -The GIT_CONFIG_LOCAL environment variable on the other hand only changes -the name used instead of the repository configuration file. The global and -the system-wide configuration files will still be read. (For writing options -this will obviously result in the same behavior as using GIT_CONFIG.) - ENVIRONMENT ----------- @@ -205,10 +200,6 @@ GIT_CONFIG:: Using the "--global" option forces this to ~/.gitconfig. Using the "--system" option forces this to $(prefix)/etc/gitconfig. -GIT_CONFIG_LOCAL:: - Take the configuration from the given file instead if .git/config. - Still read the global and the system-wide configuration files, though. - See also <>. diff --git a/builtin-config.c b/builtin-config.c index 3a441ef648..39f63d7b10 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -81,12 +81,10 @@ static int get_value(const char* key_, const char* regex_) char *global = NULL, *repo_config = NULL; const char *system_wide = NULL, *local; - local = getenv(CONFIG_ENVIRONMENT); + local = config_exclusive_filename; if (!local) { const char *home = getenv("HOME"); - local = getenv(CONFIG_LOCAL_ENVIRONMENT); - if (!local) - local = repo_config = xstrdup(git_path("config")); + local = repo_config = xstrdup(git_path("config")); if (git_config_global() && home) global = xstrdup(mkpath("%s/.gitconfig", home)); if (git_config_system()) @@ -289,6 +287,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) char* value; const char *file = setup_git_directory_gently(&nongit); + config_exclusive_filename = getenv(CONFIG_ENVIRONMENT); + while (1 < argc) { if (!strcmp(argv[1], "--int")) type = T_INT; @@ -309,14 +309,13 @@ int cmd_config(int argc, const char **argv, const char *prefix) char *home = getenv("HOME"); if (home) { char *user_config = xstrdup(mkpath("%s/.gitconfig", home)); - setenv(CONFIG_ENVIRONMENT, user_config, 1); - free(user_config); + config_exclusive_filename = user_config; } else { die("$HOME not set"); } } else if (!strcmp(argv[1], "--system")) - setenv(CONFIG_ENVIRONMENT, git_etc_gitconfig(), 1); + config_exclusive_filename = git_etc_gitconfig(); else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) { if (argc < 3) usage(git_config_set_usage); @@ -325,7 +324,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) argv[2]); else file = argv[2]; - setenv(CONFIG_ENVIRONMENT, file, 1); + config_exclusive_filename = file; argc--; argv++; } diff --git a/cache.h b/cache.h index 64ef86e129..bab0115b6f 100644 --- a/cache.h +++ b/cache.h @@ -298,7 +298,6 @@ static inline enum object_type object_type(unsigned int mode) #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE" #define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR" #define CONFIG_ENVIRONMENT "GIT_CONFIG" -#define CONFIG_LOCAL_ENVIRONMENT "GIT_CONFIG_LOCAL" #define EXEC_PATH_ENVIRONMENT "GIT_EXEC_PATH" #define GITATTRIBUTES_FILE ".gitattributes" #define INFOATTRIBUTES_FILE "info/attributes" @@ -743,6 +742,7 @@ extern int check_repository_format_version(const char *var, const char *value, v extern int git_config_system(void); extern int git_config_global(void); extern int config_error_nonbool(const char *); +extern const char *config_exclusive_filename; #define MAX_GITNAME (1000) extern char git_default_email[MAX_GITNAME]; diff --git a/config.c b/config.c index 58749bf416..2862cc45cb 100644 --- a/config.c +++ b/config.c @@ -16,6 +16,8 @@ static int config_linenr; static int config_file_eof; static int zlib_compression_seen; +const char *config_exclusive_filename = NULL; + static int get_next_char(void) { int c; @@ -611,31 +613,28 @@ int git_config(config_fn_t fn, void *data) { int ret = 0; char *repo_config = NULL; - const char *home = NULL, *filename; + const char *home = NULL; /* $GIT_CONFIG makes git read _only_ the given config file, * $GIT_CONFIG_LOCAL will make it process it in addition to the * global config file, the same way it would the per-repository * config file otherwise. */ - filename = getenv(CONFIG_ENVIRONMENT); - if (!filename) { - if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) - ret += git_config_from_file(fn, git_etc_gitconfig(), - data); - home = getenv("HOME"); - filename = getenv(CONFIG_LOCAL_ENVIRONMENT); - if (!filename) - filename = repo_config = xstrdup(git_path("config")); - } + if (config_exclusive_filename) + return git_config_from_file(fn, config_exclusive_filename, data); + if (git_config_system() && !access(git_etc_gitconfig(), R_OK)) + ret += git_config_from_file(fn, git_etc_gitconfig(), + data); + home = getenv("HOME"); if (git_config_global() && home) { char *user_config = xstrdup(mkpath("%s/.gitconfig", home)); if (!access(user_config, R_OK)) - ret = git_config_from_file(fn, user_config, data); + ret += git_config_from_file(fn, user_config, data); free(user_config); } - ret += git_config_from_file(fn, filename, data); + repo_config = xstrdup(git_path("config")); + ret += git_config_from_file(fn, repo_config, data); free(repo_config); return ret; } @@ -873,13 +872,10 @@ int git_config_set_multivar(const char* key, const char* value, struct lock_file *lock = NULL; const char* last_dot = strrchr(key, '.'); - config_filename = getenv(CONFIG_ENVIRONMENT); - if (!config_filename) { - config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT); - if (!config_filename) - config_filename = git_path("config"); - } - config_filename = xstrdup(config_filename); + if (config_exclusive_filename) + config_filename = xstrdup(config_exclusive_filename); + else + config_filename = xstrdup(git_path("config")); /* * Since "key" actually contains the section name and the real @@ -1136,13 +1132,10 @@ int git_config_rename_section(const char *old_name, const char *new_name) int out_fd; char buf[1024]; - config_filename = getenv(CONFIG_ENVIRONMENT); - if (!config_filename) { - config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT); - if (!config_filename) - config_filename = git_path("config"); - } - config_filename = xstrdup(config_filename); + if (config_exclusive_filename) + config_filename = xstrdup(config_exclusive_filename); + else + config_filename = xstrdup(git_path("config")); out_fd = hold_lock_file_for_update(lock, config_filename, 0); if (out_fd < 0) { ret = error("could not lock config file %s", config_filename); From c4730f35cc6507bc117a08885d88668fe02b1a7d Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 1 Jul 2008 00:44:47 +0100 Subject: [PATCH 17/93] Teach "git apply" to prepend a prefix with "--root=" With "git apply --root=", all file names in the patch are prepended with . If a "-p" value was given, the paths are stripped _before_ prepending . Wished for by HPA. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/git-apply.txt | 6 +++++- builtin-apply.c | 24 ++++++++++++++++++++++++ t/t4128-apply-root.sh | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100755 t/t4128-apply-root.sh diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index c8347637da..63fce53690 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -14,7 +14,7 @@ SYNOPSIS [--allow-binary-replacement | --binary] [--reject] [-z] [-pNUM] [-CNUM] [--inaccurate-eof] [--cached] [--whitespace=] - [--exclude=PATH] [--verbose] [...] + [--exclude=PATH] [--root=] [--verbose] [...] DESCRIPTION ----------- @@ -177,6 +177,10 @@ behavior: current patch being applied will be printed. This option will cause additional information to be reported. +--root=:: + Prepend to all filenames. If a "-p" argument was passed, too, + it is applied before prepending the new root. + Configuration ------------- diff --git a/builtin-apply.c b/builtin-apply.c index c497889312..bf528966ca 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -57,6 +57,8 @@ static int whitespace_error; static int squelch_whitespace_errors = 5; static int applied_after_fixing_ws; static const char *patch_input_file; +static const char *root; +static int root_len; static void parse_whitespace_option(const char *option) { @@ -331,6 +333,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) */ strbuf_remove(&name, 0, cp - name.buf); free(def); + if (root) + strbuf_insert(&name, 0, root, root_len); return strbuf_detach(&name, NULL); } } @@ -369,6 +373,14 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) free(def); } + if (root) { + char *ret = xmalloc(root_len + len + 1); + strcpy(ret, root); + memcpy(ret + root_len, start, len); + ret[root_len + len] = '\0'; + return ret; + } + return xmemdupz(start, len); } @@ -3118,6 +3130,18 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) inaccurate_eof = 1; continue; } + if (!strncmp(arg, "--root=", strlen("--root="))) { + arg += strlen("--root="); + root_len = strlen(arg); + if (root_len && arg[root_len + 1] != '/') { + char *new_root; + root = new_root = xmalloc(root_len + 2); + strcpy(new_root, arg); + strcpy(new_root + root_len++, "/"); + } else + root = arg; + continue; + } if (0 < prefix_length) arg = prefix_filename(prefix, prefix_length, arg); diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh new file mode 100755 index 0000000000..80b5af2b41 --- /dev/null +++ b/t/t4128-apply-root.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description='apply same filename' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + mkdir -p some/sub/dir && + echo Hello > some/sub/dir/file && + git add some/sub/dir/file + +' + +cat > patch << EOF +diff a/bla/blub/dir/file b/bla/blub/dir/file +--- a/bla/blub/dir/file ++++ b/bla/blub/dir/file +@@ -1,1 +1,1 @@ +-Hello ++Bello +EOF + +test_expect_success 'apply --root -p --index' ' + + git apply --root=some/sub -p3 --index patch && + test Bello = $(git show :some/sub/dir/file) && + test Bello = $(cat some/sub/dir/file) + +' + +test_done From 5821988f97b827f6ba81dfeebff932067c88ba6c Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 27 Jun 2008 09:22:01 +0200 Subject: [PATCH 18/93] git-gui: Implement "Stage/Unstage Line" This adds a context menu entry below "Stage/Unstage Hunk" that stages or unstages just the line under the mouse pointer. This is by itself useful, for example, if there are unrelated changes in the same hunk and the hunk cannot be split by reducing the context. The feature can also be used to split a hunk by staging a number of additions (or unstaging a number of removals) until there are enough context lines that the hunk gets split. The implementation reads the complete hunk that the line lives in, and constructs a new hunk by picking existing context lines, removing unneeded change lines and transforming other change lines to context lines. The resulting hunk is fed through 'git apply' just like in the "Stage/Unstage Hunk" case. Signed-off-by: Johannes Sixt Signed-off-by: Shawn O. Pearce --- git-gui.sh | 8 +++++ lib/diff.tcl | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/git-gui.sh b/git-gui.sh index 1bbae15a50..d89f156fd5 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -2666,6 +2666,11 @@ $ctxm add command \ -command {apply_hunk $cursorX $cursorY} set ui_diff_applyhunk [$ctxm index last] lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state] +$ctxm add command \ + -label [mc "Apply/Reverse Line"] \ + -command {apply_line $cursorX $cursorY; do_rescan} +set ui_diff_applyline [$ctxm index last] +lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state] $ctxm add separator $ctxm add command \ -label [mc "Show Less Context"] \ @@ -2714,8 +2719,10 @@ proc popup_diff_menu {ctxm x y X Y} { set ::cursorY $y if {$::ui_index eq $::current_diff_side} { set l [mc "Unstage Hunk From Commit"] + set t [mc "Unstage Line From Commit"] } else { set l [mc "Stage Hunk For Commit"] + set t [mc "Stage Line For Commit"] } if {$::is_3way_diff || $current_diff_path eq {} @@ -2726,6 +2733,7 @@ proc popup_diff_menu {ctxm x y X Y} { set s normal } $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l + $ctxm entryconf $::ui_diff_applyline -state $s -label $t tk_popup $ctxm $X $Y } bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y] diff --git a/lib/diff.tcl b/lib/diff.tcl index d04f6dbde2..96ba94906c 100644 --- a/lib/diff.tcl +++ b/lib/diff.tcl @@ -362,3 +362,90 @@ proc apply_hunk {x y} { set current_diff_path $current_diff_path } } + +proc apply_line {x y} { + global current_diff_path current_diff_header current_diff_side + global ui_diff ui_index file_states + + if {$current_diff_path eq {} || $current_diff_header eq {}} return + if {![lock_index apply_hunk]} return + + set apply_cmd {apply --cached --whitespace=nowarn} + set mi [lindex $file_states($current_diff_path) 0] + if {$current_diff_side eq $ui_index} { + set failed_msg [mc "Failed to unstage selected line."] + set to_context {+} + lappend apply_cmd --reverse + if {[string index $mi 0] ne {M}} { + unlock_index + return + } + } else { + set failed_msg [mc "Failed to stage selected line."] + set to_context {-} + if {[string index $mi 1] ne {M}} { + unlock_index + return + } + } + + set the_l [$ui_diff index @$x,$y] + + # operate only on change lines + set c1 [$ui_diff get "$the_l linestart"] + if {$c1 ne {+} && $c1 ne {-}} { + unlock_index + return + } + set sign $c1 + + set i_l [$ui_diff search -backwards -regexp ^@@ $the_l 0.0] + if {$i_l eq {}} { + unlock_index + return + } + # $i_l is now at the beginning of a line + + # pick start line number from hunk header + set hh [$ui_diff get $i_l "$i_l + 1 lines"] + set hh [lindex [split $hh ,] 0] + set hln [lindex [split $hh -] 1] + + set n 0 + set i_l [$ui_diff index "$i_l + 1 lines"] + set patch {} + while {[$ui_diff compare $i_l < "end - 1 chars"] && + [$ui_diff get $i_l "$i_l + 2 chars"] ne {@@}} { + set next_l [$ui_diff index "$i_l + 1 lines"] + set c1 [$ui_diff get $i_l] + if {[$ui_diff compare $i_l <= $the_l] && + [$ui_diff compare $the_l < $next_l]} { + # the line to stage/unstage + set ln [$ui_diff get $i_l $next_l] + set patch "$patch$ln" + } elseif {$c1 ne {-} && $c1 ne {+}} { + # context line + set ln [$ui_diff get $i_l $next_l] + set patch "$patch$ln" + set n [expr $n+1] + } elseif {$c1 eq $to_context} { + # turn change line into context line + set ln [$ui_diff get "$i_l + 1 chars" $next_l] + set patch "$patch $ln" + set n [expr $n+1] + } + set i_l $next_l + } + set patch "@@ -$hln,$n +$hln,[eval expr $n $sign 1] @@\n$patch" + + if {[catch { + set p [eval git_write $apply_cmd] + fconfigure $p -translation binary -encoding binary + puts -nonewline $p $current_diff_header + puts -nonewline $p $patch + close $p} err]} { + error_popup [append $failed_msg "\n\n$err"] + } + + unlock_index +} From 8ee4a6c2ec6738cfbc815dc59e44825f2a9b9f15 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 2 Jul 2008 15:28:22 -0700 Subject: [PATCH 19/93] apply --root: thinkofix. The end of a string is string[length-1], not string[length+1]. I pointed it out during the review, but I forgot about it when applying the patch. This should fix it. Signed-off-by: Junio C Hamano --- builtin-apply.c | 4 ++-- t/t4128-apply-root.sh | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index bf528966ca..6c3db60b65 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -3130,10 +3130,10 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) inaccurate_eof = 1; continue; } - if (!strncmp(arg, "--root=", strlen("--root="))) { + if (!prefixcmp(arg, "--root=")) { arg += strlen("--root="); root_len = strlen(arg); - if (root_len && arg[root_len + 1] != '/') { + if (root_len && arg[root_len - 1] != '/') { char *new_root; root = new_root = xmalloc(root_len + 2); strcpy(new_root, arg); diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index 80b5af2b41..b650245455 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -8,7 +8,9 @@ test_expect_success 'setup' ' mkdir -p some/sub/dir && echo Hello > some/sub/dir/file && - git add some/sub/dir/file + git add some/sub/dir/file && + git commit -m initial && + git tag initial ' @@ -21,7 +23,7 @@ diff a/bla/blub/dir/file b/bla/blub/dir/file +Bello EOF -test_expect_success 'apply --root -p --index' ' +test_expect_success 'apply --root -p (1)' ' git apply --root=some/sub -p3 --index patch && test Bello = $(git show :some/sub/dir/file) && @@ -29,4 +31,13 @@ test_expect_success 'apply --root -p --index' ' ' +test_expect_success 'apply --root -p (2) ' ' + + git reset --hard initial && + git apply --root=some/sub/ -p3 --index patch && + test Bello = $(git show :some/sub/dir/file) && + test Bello = $(cat some/sub/dir/file) + +' + test_done From f444e5286ee8986adb0899f85cc292fc2cd7cd04 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Jul 2008 00:37:40 -0700 Subject: [PATCH 20/93] Work around gcc warnings from curl headers After master.k.org upgrade, I started seeing these warning messages: transport.c: In function 'get_refs_via_curl': transport.c:458: error: call to '_curl_easy_setopt_err_write_callback' declared with attribute warning: curl_easy_setopt expects a curl_write_callback argument for this option It appears that the curl header wants to enforce the function signature for callback function given to curl_easy_setopt() to be compatible with that of (*curl_write_callback) or fwrite. This patch seems to work the issue around. Signed-off-by: Junio C Hamano --- http.c | 13 +++++++------ http.h | 9 +++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/http.c b/http.c index 105dc93843..ad14640412 100644 --- a/http.c +++ b/http.c @@ -30,10 +30,11 @@ static struct curl_slist *pragma_header; static struct active_request_slot *active_queue_head = NULL; -size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, - struct buffer *buffer) +size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, void *buffer_) { size_t size = eltsize * nmemb; + struct buffer *buffer = buffer_; + if (size > buffer->buf.len - buffer->posn) size = buffer->buf.len - buffer->posn; memcpy(ptr, buffer->buf.buf + buffer->posn, size); @@ -42,17 +43,17 @@ size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, return size; } -size_t fwrite_buffer(const void *ptr, size_t eltsize, - size_t nmemb, struct strbuf *buffer) +size_t fwrite_buffer(const void *ptr, size_t eltsize, size_t nmemb, void *buffer_) { size_t size = eltsize * nmemb; + struct strbuf *buffer = buffer_; + strbuf_add(buffer, ptr, size); data_received++; return size; } -size_t fwrite_null(const void *ptr, size_t eltsize, - size_t nmemb, struct strbuf *buffer) +size_t fwrite_null(const void *ptr, size_t eltsize, size_t nmemb, void *strbuf) { data_received++; return eltsize * nmemb; diff --git a/http.h b/http.h index a04fc6a927..905b4629a4 100644 --- a/http.h +++ b/http.h @@ -64,12 +64,9 @@ struct buffer }; /* Curl request read/write callbacks */ -extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, - struct buffer *buffer); -extern size_t fwrite_buffer(const void *ptr, size_t eltsize, - size_t nmemb, struct strbuf *buffer); -extern size_t fwrite_null(const void *ptr, size_t eltsize, - size_t nmemb, struct strbuf *buffer); +extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, void *strbuf); +extern size_t fwrite_buffer(const void *ptr, size_t eltsize, size_t nmemb, void *strbuf); +extern size_t fwrite_null(const void *ptr, size_t eltsize, size_t nmemb, void *strbuf); /* Slot lifecycle functions */ extern struct active_request_slot *get_active_slot(void); From 41872fd573601b123da00294f77d7d4c25db6010 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Fri, 4 Jul 2008 08:43:19 +0200 Subject: [PATCH 21/93] t4127-apply-same-fn: Avoid sed -i Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- t/t4127-apply-same-fn.sh | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index 2a6ed77c65..1f859dd908 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -4,6 +4,11 @@ test_description='apply same filename' . ./test-lib.sh +modify () { + sed -e "$1" < "$2" > "$2".x && + mv "$2".x "$2" +} + test_expect_success setup ' for i in a b c d e f g h i j k l m do @@ -14,10 +19,10 @@ test_expect_success setup ' git commit -m initial ' test_expect_success 'apply same filename with independent changes' ' - sed -i -e "s/^d/z/" same_fn && + modify "s/^d/z/" same_fn && git diff > patch0 && git add same_fn && - sed -i -e "s/^i/y/" same_fn && + modify "s/^i/y/" same_fn && git diff >> patch0 && cp same_fn same_fn2 && git reset --hard && @@ -27,10 +32,10 @@ test_expect_success 'apply same filename with independent changes' ' test_expect_success 'apply same filename with overlapping changes' ' git reset --hard - sed -i -e "s/^d/z/" same_fn && + modify "s/^d/z/" same_fn && git diff > patch0 && git add same_fn && - sed -i -e "s/^e/y/" same_fn && + modify "s/^e/y/" same_fn && git diff >> patch0 && cp same_fn same_fn2 && git reset --hard && @@ -41,10 +46,10 @@ test_expect_success 'apply same filename with overlapping changes' ' test_expect_success 'apply same new filename after rename' ' git reset --hard git mv same_fn new_fn - sed -i -e "s/^d/z/" new_fn && + modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && - sed -i -e "s/^e/y/" new_fn && + modify "s/^e/y/" new_fn && git diff >> patch1 && cp new_fn new_fn2 && git reset --hard && @@ -55,11 +60,11 @@ test_expect_success 'apply same new filename after rename' ' test_expect_success 'apply same old filename after rename -- should fail.' ' git reset --hard git mv same_fn new_fn - sed -i -e "s/^d/z/" new_fn && + modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && git mv new_fn same_fn - sed -i -e "s/^e/y/" same_fn && + modify "s/^e/y/" same_fn && git diff >> patch1 && git reset --hard && test_must_fail git apply patch1 @@ -68,15 +73,15 @@ test_expect_success 'apply same old filename after rename -- should fail.' ' test_expect_success 'apply A->B (rename), C->A (rename), A->A -- should pass.' ' git reset --hard git mv same_fn new_fn - sed -i -e "s/^d/z/" new_fn && + modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && git commit -m "a rename" && git mv other_fn same_fn - sed -i -e "s/^e/y/" same_fn && + modify "s/^e/y/" same_fn && git add same_fn && git diff -M --cached >> patch1 && - sed -i -e "s/^g/x/" same_fn && + modify "s/^g/x/" same_fn && git diff >> patch1 && git reset --hard HEAD^ && git apply patch1 From 2b2828b452bd8b3258de75451f77362decb1dffe Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Jul 2008 01:38:34 -0700 Subject: [PATCH 22/93] Fix executable bits in t/ scripts Pointed out by Ramsay Jones. Signed-off-by: Junio C Hamano --- t/t5304-prune.sh | 0 t/t7610-mergetool.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 t/t5304-prune.sh mode change 100644 => 100755 t/t7610-mergetool.sh diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh old mode 100644 new mode 100755 diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh old mode 100644 new mode 100755 From 78e3118685bc2050b4ee9ab754dcd79eb2ed4fb7 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Jul 2008 01:12:54 -0700 Subject: [PATCH 23/93] GIT 1.5.6.2 Signed-off-by: Junio C Hamano --- Documentation/RelNotes-1.5.6.2.txt | 33 +++++++++++++++++++----------- Documentation/git.txt | 3 ++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/Documentation/RelNotes-1.5.6.2.txt b/Documentation/RelNotes-1.5.6.2.txt index 02d5910d5c..5902a85a78 100644 --- a/Documentation/RelNotes-1.5.6.2.txt +++ b/Documentation/RelNotes-1.5.6.2.txt @@ -11,21 +11,30 @@ Futureproof Fixes since v1.5.6.1 -------------------- +* "git clone" from a remote that is named with url.insteadOf setting in + $HOME/.gitconfig did not work well. + +* "git describe --long --tags" segfaulted when the described revision was + tagged with a lightweight tag. + +* "git diff --check" did not report the result via its exit status + reliably. + +* When remote side used to have branch 'foo' and git-fetch finds that now + it has branch 'foo/bar', it refuses to lose the existing remote tracking + branch and its reflog. The error message has been improved to suggest + pruning the remote if the user wants to proceed and get the latest set + of branches from the remote, including such 'foo/bar'. + +* "git reset file" should mean the same thing as "git reset HEAD file", + but we required disambiguating -- even when "file" is not ambiguous. + +* "git show" segfaulted when an annotated tag that points at another + annotated tag was given to it. + * Optimization for a large import via "git-svn" introduced in v1.5.6 had a serious memory and temporary file leak, which made it unusable for moderately large import. * "git-svn" mangled remote nickname used in the configuration file unnecessarily. - -* "git diff --check" did not report the result via its exit status - reliably. - -* "git show" segfaulted when an annotated tag that points at another - annotated tag was given to it. - --- -exec >/var/tmp/1 -echo O=$(git describe maint) -O=v1.5.6.1-13-g4f3dcc2 -git shortlog --no-merges $O..maint diff --git a/Documentation/git.txt b/Documentation/git.txt index 85468a154d..0d6fe9cf79 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.5.6.1/git.html[documentation for release 1.5.6.1] +* link:v1.5.6.2/git.html[documentation for release 1.5.6.2] * release notes for + link:RelNotes-1.5.6.2.txt[1.5.6.2]. link:RelNotes-1.5.6.1.txt[1.5.6.1]. link:RelNotes-1.5.6.txt[1.5.6]. From 6cf91492d9cd985e1fa65181d99d6d578d4439dc Mon Sep 17 00:00:00 2001 From: Thomas Rast Date: Fri, 4 Jul 2008 21:10:14 +0200 Subject: [PATCH 24/93] Fix apply --recount handling of no-EOL line If a patch modifies the last line of a file that previously had no terminating '\n', it looks like -old text \ No newline at end of file +new text Hence, a '\' line does not signal the end of the hunk. This modifies 'git apply --recount' to take this into account. Signed-off-by: Thomas Rast Acked-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-apply.c | 2 +- t/t4100-apply-stat.sh | 2 ++ t/t4100/t-apply-8.expect | 2 ++ t/t4100/t-apply-8.patch | 11 +++++++++++ t/t4100/t-apply-9.expect | 2 ++ t/t4100/t-apply-9.patch | 11 +++++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 t/t4100/t-apply-8.expect create mode 100644 t/t4100/t-apply-8.patch create mode 100644 t/t4100/t-apply-9.expect create mode 100644 t/t4100/t-apply-9.patch diff --git a/builtin-apply.c b/builtin-apply.c index 9fcfe3955d..c0f867daed 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -919,7 +919,7 @@ static void recount_diff(char *line, int size, struct fragment *fragment) newlines++; continue; case '\\': - break; + continue; case '@': ret = size < 3 || prefixcmp(line, "@@ "); break; diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh index be837bb98d..e0c67740a5 100755 --- a/t/t4100-apply-stat.sh +++ b/t/t4100-apply-stat.sh @@ -33,6 +33,8 @@ mode non git (1) non git (2) non git (3) +incomplete (1) +incomplete (2) EOF test_done diff --git a/t/t4100/t-apply-8.expect b/t/t4100/t-apply-8.expect new file mode 100644 index 0000000000..eef7f2e65c --- /dev/null +++ b/t/t4100/t-apply-8.expect @@ -0,0 +1,2 @@ + t/t4100-apply-stat.sh | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/t/t4100/t-apply-8.patch b/t/t4100/t-apply-8.patch new file mode 100644 index 0000000000..5ca13e6594 --- /dev/null +++ b/t/t4100/t-apply-8.patch @@ -0,0 +1,11 @@ +diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh +index be837bb..0798c64 100755 +--- a/t/t4100-apply-stat.sh ++++ b/t/t4100-apply-stat.sh +@@ -35,4 +35,4 @@ non git (2) + non git (3) + EOF + +-test_done ++test_done +\ No newline at end of file diff --git a/t/t4100/t-apply-9.expect b/t/t4100/t-apply-9.expect new file mode 100644 index 0000000000..eef7f2e65c --- /dev/null +++ b/t/t4100/t-apply-9.expect @@ -0,0 +1,2 @@ + t/t4100-apply-stat.sh | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/t/t4100/t-apply-9.patch b/t/t4100/t-apply-9.patch new file mode 100644 index 0000000000..875d57d567 --- /dev/null +++ b/t/t4100/t-apply-9.patch @@ -0,0 +1,11 @@ +diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh +index 0798c64..be837bb 100755 +--- a/t/t4100-apply-stat.sh ++++ b/t/t4100-apply-stat.sh +@@ -35,4 +35,4 @@ non git (2) + non git (3) + EOF + +-test_done +\ No newline at end of file ++test_done From 51add76e92c9de9bcad3d421303b45ab488d529e Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sat, 5 Jul 2008 16:43:51 +0200 Subject: [PATCH 25/93] Retire 'stupid' merge strategy As pointed out by Linus, this strategy tries to take the best merge base, but 'recursive' just does it better. If one needs something more than 'resolve' then he/she should really use 'recursive' and not 'stupid'. Cf. Message-ID: Signed-off-by: Junio C Hamano --- .gitignore | 1 - Makefile | 3 +- git-merge-stupid.sh | 80 --------------------------------------------- 3 files changed, 1 insertion(+), 83 deletions(-) delete mode 100755 git-merge-stupid.sh diff --git a/.gitignore b/.gitignore index 4ff2fec278..8054d9ddb8 100644 --- a/.gitignore +++ b/.gitignore @@ -75,7 +75,6 @@ git-merge-one-file git-merge-ours git-merge-recursive git-merge-resolve -git-merge-stupid git-merge-subtree git-mergetool git-mktag diff --git a/Makefile b/Makefile index 78e08d3745..bddd1a7e48 100644 --- a/Makefile +++ b/Makefile @@ -241,7 +241,6 @@ SCRIPT_SH += git-merge-octopus.sh SCRIPT_SH += git-merge-one-file.sh SCRIPT_SH += git-merge-resolve.sh SCRIPT_SH += git-merge.sh -SCRIPT_SH += git-merge-stupid.sh SCRIPT_SH += git-mergetool.sh SCRIPT_SH += git-parse-remote.sh SCRIPT_SH += git-pull.sh @@ -1429,7 +1428,7 @@ check-docs:: do \ case "$$v" in \ git-merge-octopus | git-merge-ours | git-merge-recursive | \ - git-merge-resolve | git-merge-stupid | git-merge-subtree | \ + git-merge-resolve | git-merge-subtree | \ git-fsck-objects | git-init-db | \ git-?*--?* ) continue ;; \ esac ; \ diff --git a/git-merge-stupid.sh b/git-merge-stupid.sh deleted file mode 100755 index f612d4729c..0000000000 --- a/git-merge-stupid.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2005 Linus Torvalds -# -# Resolve two trees, 'stupid merge'. - -# The first parameters up to -- are merge bases; the rest are heads. -bases= head= remotes= sep_seen= -for arg -do - case ",$sep_seen,$head,$arg," in - *,--,) - sep_seen=yes - ;; - ,yes,,*) - head=$arg - ;; - ,yes,*) - remotes="$remotes$arg " - ;; - *) - bases="$bases$arg " - ;; - esac -done - -# Give up if we are given two or more remotes -- not handling octopus. -case "$remotes" in -?*' '?*) - exit 2 ;; -esac - -# Find an optimum merge base if there are more than one candidates. -case "$bases" in -?*' '?*) - echo "Trying to find the optimum merge base." - G=.tmp-index$$ - best= - best_cnt=-1 - for c in $bases - do - rm -f $G - GIT_INDEX_FILE=$G git read-tree -m $c $head $remotes \ - 2>/dev/null || continue - # Count the paths that are unmerged. - cnt=`GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l` - if test $best_cnt -le 0 -o $cnt -le $best_cnt - then - best=$c - best_cnt=$cnt - if test "$best_cnt" -eq 0 - then - # Cannot do any better than all trivial merge. - break - fi - fi - done - rm -f $G - common="$best" - ;; -*) - common="$bases" - ;; -esac - -git update-index --refresh 2>/dev/null -git read-tree -u -m $common $head $remotes || exit 2 -echo "Trying simple merge." -if result_tree=$(git write-tree 2>/dev/null) -then - exit 0 -else - echo "Simple merge failed, trying Automatic merge." - if git-merge-index -o git-merge-one-file -a - then - exit 0 - else - exit 1 - fi -fi From 9c67c757191b34760bf5f6c1d1426ce1bb01ef08 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 2 Jul 2008 23:47:05 -0500 Subject: [PATCH 26/93] git-format-patch(1): fix stray \ in output In listing blocks (set off by rows of dashes), the usual formatting characters of asciidoc are instead rendered verbatim. When the escaped double-hyphen of olden days is moved into such a block along with other formatting improvements, it becomes backslash-dash-dash. So we remove the backslash. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-format-patch.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 894b82d6be..3c9192a6cf 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -206,7 +206,7 @@ For each commit a separate file is created in the current directory. project: + ------------ -$ git format-patch \--root origin +$ git format-patch --root origin ------------ * The same as the previous one: From 0cafe944e9c1d50e0b4377fbf26f2fc1544d0204 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Wed, 2 Jul 2008 23:54:38 -0500 Subject: [PATCH 27/93] Documentation: fix gitlinks Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-repack.txt | 2 +- Documentation/user-manual.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index 0d72e83023..c956affb43 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -72,7 +72,7 @@ OPTIONS `git-update-server-info`. This option skips updating local catalog files needed to publish this repository (or a direct copy of it) - over HTTP or FTP. See gitlink:git-update-server-info[1]. + over HTTP or FTP. See linkgit:git-update-server-info[1]. --window=[N]:: --depth=[N]:: diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index ca13266b11..cbfc5d03a3 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1303,7 +1303,7 @@ $ git diff -3 file.txt # diff against stage 3 $ git diff --theirs file.txt # same as the above. ------------------------------------------------- -The linkgit:git-log[1] and gitk[1] commands also provide special help +The linkgit:git-log[1] and linkgit:gitk[1] commands also provide special help for merges: ------------------------------------------------- From 7f9d77f2797cabfc1b5b9bad89a295d4f139120f Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:03:54 -0500 Subject: [PATCH 28/93] manpages: fix bogus whitespace It's distracting. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-fast-import.txt | 2 +- Documentation/git-format-patch.txt | 8 ++++---- Documentation/git-gui.txt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 70cc8e831f..960276423b 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -86,7 +86,7 @@ OPTIONS --quiet:: Disable all non-fatal output, making fast-import silent when it - is successful. This option disables the output shown by + is successful. This option disables the output shown by \--stats. --stats:: diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 3c9192a6cf..b990052f57 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -175,10 +175,10 @@ and file suffix, and number patches when outputting more than one. ------------ [format] - headers = "Organization: git-foo\n" - subjectprefix = CHANGE - suffix = .txt - numbered = auto + headers = "Organization: git-foo\n" + subjectprefix = CHANGE + suffix = .txt + numbered = auto cc = ------------ diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt index 940e43f37e..ea1e4ce624 100644 --- a/Documentation/git-gui.txt +++ b/Documentation/git-gui.txt @@ -34,7 +34,7 @@ blame:: browser:: Start a tree browser showing all files in the specified - commit (or 'HEAD' by default). Files selected through the + commit (or 'HEAD' by default). Files selected through the browser are opened in the blame viewer. citool:: @@ -61,7 +61,7 @@ git gui blame Makefile:: git gui blame v0.99.8 Makefile:: Show the contents of 'Makefile' in revision 'v0.99.8' - and provide annotations for each line. Unlike the above + and provide annotations for each line. Unlike the above example the file is read from the object database and not the working directory. From 56992f765d8e5eaa495f46e23f50b17ec1db725f Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:08:12 -0500 Subject: [PATCH 29/93] git(1): add comma Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index 425f1f4aee..0ede9b9967 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -142,7 +142,7 @@ help ...'. --exec-path:: Path to wherever your core git programs are installed. This can also be controlled by setting the GIT_EXEC_PATH - environment variable. If no path is given 'git' will print + environment variable. If no path is given, 'git' will print the current setting and then exit. -p:: From d69806d198398d11d40e735538eb5f9402ef315f Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:13:45 -0500 Subject: [PATCH 30/93] git-commit(1): depersonalize description The intent is to make git-commit(1) feel more like a manual page. The change also makes the page four words shorter. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-commit.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 03594cd5dc..dd1cc2f4a1 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -15,8 +15,8 @@ SYNOPSIS DESCRIPTION ----------- -Use 'git commit' to store the current contents of the index in a new -commit along with a log message describing the changes you have made. +Stores the current contents of the index in a new commit along +with a log message from the user describing the changes. The content to be added can be specified in several ways: From 7a7d4ef69c2c79b10977508794e1bbd62ca9ed2b Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:20:21 -0500 Subject: [PATCH 31/93] Documentation: rewrap to prepare for "git-" vs "git " change Rewrap lines in preparation for added dashes. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/config.txt | 4 ++-- Documentation/user-manual.txt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 561ff645f9..bb12f0332d 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -627,8 +627,8 @@ gc.autopacklimit:: gc.packrefs:: `git gc` does not run `git pack-refs` in a bare repository by default so that older dumb-transport clients can still fetch - from the repository. Setting this to `true` lets `git - gc` to run `git pack-refs`. Setting this to `false` tells + from the repository. Setting this to `true` lets `git gc` + to run `git pack-refs`. Setting this to `false` tells `git gc` never to run `git pack-refs`. The default setting is `notbare`. Enable it only when you know you do not have to support such clients. The default setting will change to `true` diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index cbfc5d03a3..61cf30f8f4 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -2443,8 +2443,8 @@ patches to the new mywork. The result will look like: ................................................ In the process, it may discover conflicts. In that case it will stop -and allow you to fix the conflicts; after fixing conflicts, use "git -add" to update the index with those contents, and then, instead of +and allow you to fix the conflicts; after fixing conflicts, use "git add" +to update the index with those contents, and then, instead of running git-commit, just run ------------------------------------------------- @@ -2700,8 +2700,8 @@ master branch. In more detail: git fetch and fast-forwards --------------------------- -In the previous example, when updating an existing branch, "git -fetch" checks to make sure that the most recent commit on the remote +In the previous example, when updating an existing branch, "git fetch" +checks to make sure that the most recent commit on the remote branch is a descendant of the most recent commit on your copy of the branch before updating your copy of the branch to point at the new commit. Git calls this process a <>. From 467c0197fd0a49078d05839ee385046cd3707a5b Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:28:15 -0500 Subject: [PATCH 32/93] Documentation: more "git-" versus "git " changes With git-commands moving out of $(bindir), it is useful to make a clearer distinction between the git subcommand 'git-whatever' and the command you type, `git whatever `. So we use a dash after "git" when referring to the former and not the latter. I already sent a patch doing this same thing, but I missed some spots. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/config.txt | 52 ++++++++++++++--------------- Documentation/git-bisect.txt | 4 +-- Documentation/git-commit.txt | 2 +- Documentation/git-filter-branch.txt | 2 +- Documentation/git-format-patch.txt | 2 +- Documentation/git-help.txt | 2 +- Documentation/git-rebase.txt | 4 +-- Documentation/git-reflog.txt | 2 +- Documentation/git-remote.txt | 2 +- Documentation/git-rerere.txt | 2 +- Documentation/git-shortlog.txt | 2 +- Documentation/gitcore-tutorial.txt | 30 ++++++++--------- Documentation/user-manual.txt | 36 ++++++++++---------- 13 files changed, 71 insertions(+), 71 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index bb12f0332d..13b17a5a1e 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -356,8 +356,8 @@ core.pager:: core.whitespace:: A comma separated list of common whitespace problems to - notice. `git diff` will use `color.diff.whitespace` to - highlight them, and `git apply --whitespace=error` will + notice. `git-diff` will use `color.diff.whitespace` to + highlight them, and `git-apply --whitespace=error` will consider them as errors: + * `trailing-space` treats trailing whitespaces at the end of the line @@ -426,20 +426,20 @@ branch.autosetuprebase:: This option defaults to never. branch..remote:: - When in branch , it tells `git fetch` which remote to fetch. - If this option is not given, `git fetch` defaults to remote "origin". + When in branch , it tells `git-fetch` which remote to fetch. + If this option is not given, `git-fetch` defaults to remote "origin". branch..merge:: - When in branch , it tells `git fetch` the default + When in branch , it tells `git-fetch` the default refspec to be marked for merging in FETCH_HEAD. The value is handled like the remote part of a refspec, and must match a ref which is fetched from the remote given by "branch..remote". - The merge information is used by `git pull` (which at first calls - `git fetch`) to lookup the default branch for merging. Without - this option, `git pull` defaults to merge the first refspec fetched. + The merge information is used by `git-pull` (which at first calls + `git-fetch`) to lookup the default branch for merging. Without + this option, `git-pull` defaults to merge the first refspec fetched. Specify multiple values to get an octopus merge. - If you wish to setup `git pull` so that it merges into from + If you wish to setup `git-pull` so that it merges into from another branch in the local repository, you can point branch..merge to the desired branch, and use the special setting `.` (a period) for branch..remote. @@ -508,12 +508,12 @@ color.diff.:: color.interactive:: When set to `always`, always use colors for interactive prompts - and displays (such as those used by "git add --interactive"). + and displays (such as those used by "git-add --interactive"). When false (or `never`), never. When set to `true` or `auto`, use colors only when the output is to the terminal. Defaults to false. color.interactive.:: - Use customized color for `git add --interactive` + Use customized color for `git-add --interactive` output. `` may be `prompt`, `header`, or `help`, for three distinct types of normal output from interactive programs. The values of these variables may be specified as @@ -550,14 +550,14 @@ color.ui:: take precedence over this setting. Defaults to false. diff.autorefreshindex:: - When using `git diff` to compare with work tree + When using `git-diff` to compare with work tree files, do not consider stat-only change as changed. Instead, silently run `git update-index --refresh` to update the cached stat information for paths whose contents in the work tree match the contents in the index. This option defaults to true. Note that this - affects only `git diff` Porcelain, and not lower level - `diff` commands, such as `git diff-files`. + affects only `git-diff` Porcelain, and not lower level + `diff` commands, such as `git-diff-files`. diff.external:: If this config variable is set, diff generation is not @@ -568,7 +568,7 @@ diff.external:: diff.renameLimit:: The number of files to consider when performing the copy/rename - detection; equivalent to the git diff option '-l'. + detection; equivalent to the git-diff option '-l'. diff.renames:: Tells git to detect renames. If set to any boolean value, it @@ -608,7 +608,7 @@ format.pretty:: gc.aggressiveWindow:: The window size parameter used in the delta compression - algorithm used by 'git gc --aggressive'. This defaults + algorithm used by 'git-gc --aggressive'. This defaults to 10. gc.auto:: @@ -625,37 +625,37 @@ gc.autopacklimit:: default value is 50. Setting this to 0 disables it. gc.packrefs:: - `git gc` does not run `git pack-refs` in a bare repository by + `git-gc` does not run `git pack-refs` in a bare repository by default so that older dumb-transport clients can still fetch - from the repository. Setting this to `true` lets `git gc` + from the repository. Setting this to `true` lets `git-gc` to run `git pack-refs`. Setting this to `false` tells - `git gc` never to run `git pack-refs`. The default setting is + `git-gc` never to run `git pack-refs`. The default setting is `notbare`. Enable it only when you know you do not have to support such clients. The default setting will change to `true` at some stage, and setting this to `false` will continue to - prevent `git pack-refs` from being run from `git gc`. + prevent `git pack-refs` from being run from `git-gc`. gc.pruneexpire:: - When `git gc` is run, it will call `prune --expire 2.weeks.ago`. + When `git-gc` is run, it will call `prune --expire 2.weeks.ago`. Override the grace period with this config variable. gc.reflogexpire:: - `git reflog expire` removes reflog entries older than + `git-reflog expire` removes reflog entries older than this time; defaults to 90 days. gc.reflogexpireunreachable:: - `git reflog expire` removes reflog entries older than + `git-reflog expire` removes reflog entries older than this time and are not reachable from the current tip; defaults to 30 days. gc.rerereresolved:: Records of conflicted merge you resolved earlier are - kept for this many days when `git rerere gc` is run. + kept for this many days when `git-rerere gc` is run. The default is 60 days. See linkgit:git-rerere[1]. gc.rerereunresolved:: Records of conflicted merge you have not resolved are - kept for this many days when `git rerere gc` is run. + kept for this many days when `git-rerere gc` is run. The default is 15 days. See linkgit:git-rerere[1]. rerere.enabled:: @@ -844,7 +844,7 @@ instaweb.port:: log.date:: Set default date-time mode for the log command. Setting log.date - value is similar to using git log's --date option. The value is one of + value is similar to using git-log's --date option. The value is one of the following alternatives: {relative,local,default,iso,rfc,short}. See linkgit:git-log[1]. diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 8bbcb940fb..a13983fda7 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -26,7 +26,7 @@ on the subcommand: git bisect log git bisect run ... -This command uses `git rev-list --bisect` to help drive the +This command uses `git-rev-list --bisect` to help drive the binary search process to find which change introduced a bug, given an old "good" commit object name and a later "bad" commit object name. @@ -101,7 +101,7 @@ $ git bisect visualize to see the currently remaining suspects in `gitk`. `visualize` is a bit too long to type and `view` is provided as a synonym. -If `DISPLAY` environment variable is not set, `git log` is used +If 'DISPLAY' environment variable is not set, `git-log` is used instead. You can even give command line options such as `-p` and `--stat`. diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index dd1cc2f4a1..03205a4077 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -155,7 +155,7 @@ but can be used to amend a merge commit. Make a commit only from the paths specified on the command line, disregarding any contents that have been staged so far. This is the default mode of operation of - 'git commit' if any paths are given on the command line, + 'git-commit' if any paths are given on the command line, in which case this option can be omitted. If this option is specified together with '--amend', then no paths need be specified, which can be used to amend diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index a9388e0e27..4262309b09 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -163,7 +163,7 @@ to other tags will be rewritten to point to the underlying commit. -f:: --force:: - `git filter-branch` refuses to start with an existing temporary + `git-filter-branch` refuses to start with an existing temporary directory or when there are already refs starting with 'refs/original/', unless forced. diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index b990052f57..41e487ae1d 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -190,7 +190,7 @@ EXAMPLES the current branch using `git-am` to cherry-pick them: + ------------ -$ git format-patch -k --stdout R1..R2 | git-am -3 -k +$ git format-patch -k --stdout R1..R2 | git am -3 -k ------------ * Extract all commits which are in the current branch but not in the diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index 5ace863c10..73ec7ad9eb 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -120,7 +120,7 @@ man..path You can explicitly provide a full path to your preferred man viewer by setting the configuration variable 'man..path'. For example, you can configure the absolute path to konqueror by setting -'man.konqueror.path'. Otherwise, 'git help' assumes the tool is +'man.konqueror.path'. Otherwise, 'git-help' assumes the tool is available in PATH. man..cmd diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 754230e462..67aa497f46 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -259,10 +259,10 @@ NOTES When you rebase a branch, you are changing its history in a way that will cause problems for anyone who already has a copy of the branch in their repository and tries to pull updates from you. You should -understand the implications of using 'git rebase' on a repository that +understand the implications of using 'git-rebase' on a repository that you share. -When the git rebase command is run, it will first execute a "pre-rebase" +When the git-rebase command is run, it will first execute a "pre-rebase" hook if one exists. You can use this hook to do sanity checks and reject the rebase if it isn't appropriate. Please see the template pre-rebase hook script for an example. diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index 8492aeacf1..d963c5155d 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -60,7 +60,7 @@ OPTIONS refs. + This computation involves traversing all the reachable objects, i.e. it -has the same cost as 'git prune'. Fortunately, once this is run, we +has the same cost as 'git-prune'. Fortunately, once this is run, we should not have to ever worry about missing objects, because the current prune and pack-objects know about reflogs and protect objects referred by them. diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 32db0aed11..3634efd8bf 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -124,7 +124,7 @@ $ git checkout -b nfs linux-nfs/master ... ------------ -* Imitate 'git clone' but track only selected branches +* Imitate 'git-clone' but track only selected branches + ------------ $ mkdir project.git diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 3458029042..ae2b2b543a 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -163,7 +163,7 @@ If this three-way merge resolves cleanly, the result is written out to your working tree file, so you would not have to manually resolve it. Note that `git-rerere` leaves the index file alone, so you still need to do the final sanity checks with `git diff` -(or `git diff -c`) and `git add` when you are satisfied. +(or `git diff -c`) and `git-add` when you are satisfied. As a convenience measure, `git-merge` automatically invokes `git-rerere` when it exits with a failed automerge, which diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index 6e4cbc4fdd..74a5f29cd8 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -3,7 +3,7 @@ git-shortlog(1) NAME ---- -git-shortlog - Summarize 'git log' output +git-shortlog - Summarize 'git-log' output SYNOPSIS -------- diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index 7d721c5b08..059c8ffd27 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -595,7 +595,7 @@ pointer to the state you want to tag, but also a small tag name and message, along with optionally a PGP signature that says that yes, you really did that tag. You create these annotated tags with either the `-a` or -`-s` flag to `git tag`: +`-s` flag to `git-tag`: ---------------- $ git tag -s @@ -642,7 +642,7 @@ and it will be gone. There's no external repository, and there's no history outside the project you created. - if you want to move or duplicate a git repository, you can do so. There - is `git clone` command, but if all you want to do is just to + is `git-clone` command, but if all you want to do is just to create a copy of your repository (with all the full history that went along with it), you can do so with a regular `cp -a git-tutorial new-git-tutorial`. @@ -776,7 +776,7 @@ to it. ================================================ If you make the decision to start your new branch at some other point in the history than the current `HEAD`, you can do so by -just telling `git checkout` what the base of the checkout would be. +just telling `git-checkout` what the base of the checkout would be. In other words, if you have an earlier tag or branch, you'd just do ------------ @@ -819,7 +819,7 @@ $ git branch [startingpoint] which will simply _create_ the branch, but will not do anything further. You can then later -- once you decide that you want to actually develop -on that branch -- switch to that branch with a regular `git checkout` +on that branch -- switch to that branch with a regular `git-checkout` with the branchname as the argument. @@ -881,7 +881,7 @@ source. Anyway, let's exit `gitk` (`^Q` or the File menu), and decide that we want to merge the work we did on the `mybranch` branch into the `master` branch (which is currently our `HEAD` too). To do that, there's a nice -script called `git merge`, which wants to know which branches you want +script called `git-merge`, which wants to know which branches you want to resolve and what the merge is all about: ------------ @@ -1023,12 +1023,12 @@ Merging external work It's usually much more common that you merge with somebody else than merging with your own branches, so it's worth pointing out that git makes that very easy too, and in fact, it's not that different from -doing a `git merge`. In fact, a remote merge ends up being nothing +doing a `git-merge`. In fact, a remote merge ends up being nothing more than "fetch the work from a remote repository into a temporary tag" -followed by a `git merge`. +followed by a `git-merge`. Fetching from a remote repository is done by, unsurprisingly, -`git fetch`: +`git-fetch`: ---------------- $ git fetch @@ -1115,7 +1115,7 @@ argument. [NOTE] You could do without using any branches at all, by keeping as many local repositories as you would like to have -branches, and merging between them with `git pull`, just like +branches, and merging between them with `git-pull`, just like you merge between branches. The advantage of this approach is that it lets you keep a set of files for each `branch` checked out and you may find it easier to switch back and forth if you @@ -1132,7 +1132,7 @@ like this: $ git config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/ ------------------------------------------------ -and use the "linus" keyword with `git pull` instead of the full URL. +and use the "linus" keyword with `git-pull` instead of the full URL. Examples. @@ -1168,7 +1168,7 @@ $ git show-branch --more=2 master mybranch +* [master^] Some fun. ------------ -Remember, before running `git merge`, our `master` head was at +Remember, before running `git-merge`, our `master` head was at "Some fun." commit, while our `mybranch` head was at "Some work." commit. @@ -1345,7 +1345,7 @@ $ mkdir my-git.git ------------ Then, make that directory into a git repository by running -`git init`, but this time, since its name is not the usual +`git-init`, but this time, since its name is not the usual `.git`, we do things slightly differently: ------------ @@ -1407,7 +1407,7 @@ $ git repack will do it for you. If you followed the tutorial examples, you would have accumulated about 17 objects in `.git/objects/??/` -directories by now. `git repack` tells you how many objects it +directories by now. `git-repack` tells you how many objects it packed, and stores the packed file in `.git/objects/pack` directory. @@ -1656,8 +1656,8 @@ $ git reset --hard master~2 ------------ You can make sure 'git show-branch' matches the state before -those two 'git merge' you just did. Then, instead of running -two 'git merge' commands in a row, you would merge these two +those two 'git-merge' you just did. Then, instead of running +two 'git-merge' commands in a row, you would merge these two branch heads (this is known as 'making an Octopus'): ------------ diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 61cf30f8f4..01c1af6b6a 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1963,10 +1963,10 @@ error: failed to push to 'ssh://yourserver.com/~you/proj.git' This can happen, for example, if you: - - use `git reset --hard` to remove already-published commits, or - - use `git commit --amend` to replace already-published commits + - use `git-reset --hard` to remove already-published commits, or + - use `git-commit --amend` to replace already-published commits (as in <>), or - - use `git rebase` to rebase any already-published commits (as + - use `git-rebase` to rebase any already-published commits (as in <>). You may force git-push to perform the update anyway by preceding the @@ -2170,7 +2170,7 @@ they are for, or what status they are in. To get a reminder of what changes are in a specific branch, use: ------------------------------------------------- -$ git log linux..branchname | git-shortlog +$ git log linux..branchname | git shortlog ------------------------------------------------- To see whether it has already been merged into the test or release branches, @@ -2443,7 +2443,7 @@ patches to the new mywork. The result will look like: ................................................ In the process, it may discover conflicts. In that case it will stop -and allow you to fix the conflicts; after fixing conflicts, use "git add" +and allow you to fix the conflicts; after fixing conflicts, use "git-add" to update the index with those contents, and then, instead of running git-commit, just run @@ -2700,7 +2700,7 @@ master branch. In more detail: git fetch and fast-forwards --------------------------- -In the previous example, when updating an existing branch, "git fetch" +In the previous example, when updating an existing branch, "git-fetch" checks to make sure that the most recent commit on the remote branch is a descendant of the most recent commit on your copy of the branch before updating your copy of the branch to point at the new @@ -2726,7 +2726,7 @@ resulting in a situation like: o--o--o <-- new head of the branch ................................................ -In this case, "git fetch" will fail, and print out a warning. +In this case, "git-fetch" will fail, and print out a warning. In that case, you can still force git to update to the new head, as described in the following section. However, note that in the @@ -3106,7 +3106,7 @@ $ git prune to remove any of the "loose" objects that are now contained in the pack. This will also remove any unreferenced objects (which may be -created when, for example, you use "git reset" to remove a commit). +created when, for example, you use "git-reset" to remove a commit). You can verify that the loose objects are gone by looking at the .git/objects directory or by running @@ -3135,7 +3135,7 @@ branch still exists, as does everything it pointed to. The branch pointer itself just doesn't, since you replaced it with another one. There are also other situations that cause dangling objects. For -example, a "dangling blob" may arise because you did a "git add" of a +example, a "dangling blob" may arise because you did a "git-add" of a file, but then, before you actually committed it and made it part of the bigger picture, you changed something else in that file and committed that *updated* thing--the old state that you added originally ends up @@ -3185,7 +3185,7 @@ Usually, dangling blobs and trees aren't very interesting. They're almost always the result of either being a half-way mergebase (the blob will often even have the conflict markers from a merge in it, if you have had conflicting merges that you fixed up by hand), or simply -because you interrupted a "git fetch" with ^C or something like that, +because you interrupted a "git-fetch" with ^C or something like that, leaving _some_ of the new objects in the object database, but just dangling and useless. @@ -3694,7 +3694,7 @@ removed. The only thing `--remove` means is that update-index will be considering a removed file to be a valid thing, and if the file really does not exist any more, it will update the index accordingly. -As a special case, you can also do `git-update-index --refresh`, which +As a special case, you can also do `git update-index --refresh`, which will refresh the "stat" information of each index to match the current stat information. It will 'not' update the object status itself, and it will only update the fields that are used to quickly test whether @@ -3770,7 +3770,7 @@ from one representation to the other: Tying it all together ~~~~~~~~~~~~~~~~~~~~~ -To commit a tree you have instantiated with "git-write-tree", you'd +To commit a tree you have instantiated with "git write-tree", you'd create a "commit" object that refers to that tree and the history behind it--most notably the "parent" commits that preceded it in history. @@ -3927,7 +3927,7 @@ $ git read-tree -m -u which will do all trivial merge operations for you directly in the index file, and you can just write the result out with -`git-write-tree`. +`git write-tree`. [[merging-multiple-trees-2]] @@ -4095,7 +4095,7 @@ functions like `get_sha1_basic()` or the likes. This is just to get you into the groove for the most libified part of Git: the revision walker. -Basically, the initial version of `git log` was a shell script: +Basically, the initial version of `git-log` was a shell script: ---------------------------------------------------------------- $ git-rev-list --pretty $(git-rev-parse --default HEAD "$@") | \ @@ -4130,7 +4130,7 @@ just have a look at the first implementation of `cmd_log()`; call `git show v1.3.0{tilde}155^2{tilde}4` and scroll down to that function (note that you no longer need to call `setup_pager()` directly). -Nowadays, `git log` is a builtin, which means that it is _contained_ in the +Nowadays, `git-log` is a builtin, which means that it is _contained_ in the command `git`. The source side of a builtin is - a function called `cmd_`, typically defined in `builtin-.c`, @@ -4146,7 +4146,7 @@ since they share quite a bit of code. In that case, the commands which are _not_ named like the `.c` file in which they live have to be listed in `BUILT_INS` in the `Makefile`. -`git log` looks more complicated in C than it does in the original script, +`git-log` looks more complicated in C than it does in the original script, but that allows for a much greater flexibility and performance. Here again it is a good point to take a pause. @@ -4157,9 +4157,9 @@ the organization of Git (after you know the basic concepts). So, think about something which you are interested in, say, "how can I access a blob just knowing the object name of it?". The first step is to find a Git command with which you can do it. In this example, it is either -`git show` or `git cat-file`. +`git-show` or `git-cat-file`. -For the sake of clarity, let's stay with `git cat-file`, because it +For the sake of clarity, let's stay with `git-cat-file`, because it - is plumbing, and From 877276d4d3018d2810be990c39fa7f59678e960d Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:30:25 -0500 Subject: [PATCH 33/93] gitdiffcore(7): fix awkward wording The phrase "diff outputs" sounds awkward to my ear (I think "output" is meant to be used as a substantive noun.) Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/gitdiffcore.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index 0b7daeda2d..1171b5c604 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -16,8 +16,8 @@ The diff commands `git-diff-index`, `git-diff-files`, and `git-diff-tree` can be told to manipulate differences they find in unconventional ways before showing `diff` output. The manipulation is collectively called "diffcore transformation". This short note -describes what they are and how to use them to produce diff outputs -that are easier to understand than the conventional kind. +describes what they are and how to use them to produce diff output +that is easier to understand than the conventional kind. The chain of operation From 04c2407eafa0361439a60fd6240447f3404d014b Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Thu, 3 Jul 2008 00:36:04 -0500 Subject: [PATCH 34/93] manpages: italicize command names in synopses To tell command names from options in a glance. Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-reflog.txt | 10 +++++----- Documentation/git-remote.txt | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index d963c5155d..1710626cfa 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -16,12 +16,12 @@ The command takes various subcommands, and different options depending on the subcommand: [verse] -git reflog expire [--dry-run] [--stale-fix] [--verbose] +'git reflog expire' [--dry-run] [--stale-fix] [--verbose] [--expire=