From 5dee29ac0fc95999a42c5cbac767724a9ff73cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 25 Jan 2007 05:45:39 +0100 Subject: [PATCH 01/47] make --upload-pack option to git-fetch configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces the config item remote..uploadpack to override the default value (which is "git-upload-pack"). Signed-off-by: Uwe Kleine-König Signed-off-by: Junio C Hamano --- Documentation/config.txt | 6 +++++- git-fetch.sh | 6 ++++++ git-parse-remote.sh | 13 +++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 8086d75368..3f2fa09a87 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -429,9 +429,13 @@ remote..push:: gitlink:git-push[1]. remote..receivepack:: - The default program to execute on the remote side when pulling. See + The default program to execute on the remote side when pushing. See option \--exec of gitlink:git-push[1]. +remote..uploadpack:: + The default program to execute on the remote side when fetching. See + option \--exec of gitlink:git-fetch-pack[1]. + repack.usedeltabaseoffset:: Allow gitlink:git-repack[1] to create packs that uses delta-base offset. Defaults to false. diff --git a/git-fetch.sh b/git-fetch.sh index 07a1d05ac7..61c8cf4773 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -85,6 +85,12 @@ case "$#" in set x $origin ; shift ;; esac +if test -z "$exec" +then + # No command line override and we have configuration for the remote. + exec="--upload-pack=$(get_uploadpack $1)" +fi + remote_nick="$1" remote=$(get_remote_url "$@") refs= diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 4fc602082b..1122c8389d 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -279,3 +279,16 @@ resolve_alternates () { esac done } + +get_uploadpack () { + data_source=$(get_data_source "$1") + case "$data_source" in + config) + uplp=$(git-repo-config --get "remote.$1.uploadpack") + echo ${uplp:-git-upload-pack} + ;; + *) + echo "git-upload-pack" + ;; + esac +} From 535514f1f3cd32dfe2cb4c70e97b41ea868d1134 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Mon, 22 Jan 2007 10:56:27 +0000 Subject: [PATCH 02/47] New files in git weren't being downloaded during CVS update If a repository was checked out via git-cvsserver and then later a new file is added to the git repository via some other method; a CVS update wasn't fetching the new file. It would be reported as a new file as A some/dir/newfile.c but would never appear in the directory. The problem seems to be that git-cvsserver was treating these two cases identically, as "A" type results. 1. New file in repository 2. New file locally In fact, traditionally, case 1 is treated as a "U" result, and case 2 only is treated as an "A" result. "A", should just report that the file is added locally and then skip that file during an update as there is (of course) nothing to send. In both these cases there is no working revision, so the checking for "is there no working revision" will return true. The test for case 2 needs refining to say "if there is no working revision and no upstream revision". This patch does just that, leaving case 1 to be handled by the normal "U" handler. I've also updated the log message to more accurately describe the operation. i.e. that "A" means that content is scheduled for addition; not that it actually has been added. Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano --- git-cvsserver.perl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git-cvsserver.perl b/git-cvsserver.perl index a33a876ff6..e18e901731 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -876,9 +876,9 @@ sub req_update print "MT newline\n"; next; } - elsif ( !defined($wrev) || $wrev == 0 ) + elsif ( (!defined($wrev) || $wrev == 0) && (!defined($meta->{revision}) || $meta->{revision} == 0) ) { - $log->info("Tell the client the file will be added"); + $log->info("Tell the client the file is scheduled for addition"); print "MT text A \n"; print "MT fname $filename\n"; print "MT newline\n"; @@ -886,7 +886,7 @@ sub req_update } else { - $log->info("Updating '$filename' $wrev"); + $log->info("Updating '$filename' to ".$meta->{revision}); print "MT +updated\n"; print "MT text U \n"; print "MT fname $filename\n"; From 1b555932cdb7f75239623573cd2ff25fa98ab4e4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Jan 2007 16:51:21 -0800 Subject: [PATCH 03/47] Fix seriously broken "git pack-refs" Do *NOT* try this on a repository you care about: git pack-refs --all --prune git pack-refs because while the first "pack-refs" does the right thing, the second pack-refs will totally screw you over. This is because the second one tries to pack only tags; we should also pack what are already packed -- otherwise we would lose them. [jc: with an additional test] Signed-off-by: Junio C Hamano --- builtin-pack-refs.c | 4 +++- t/t3210-pack-refs.sh | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c index 6de7128b9d..3de9b3eefd 100644 --- a/builtin-pack-refs.c +++ b/builtin-pack-refs.c @@ -37,7 +37,9 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, if ((flags & REF_ISSYMREF)) return 0; is_tag_ref = !strncmp(path, "refs/tags/", 10); - if (!cb->all && !is_tag_ref) + + /* ALWAYS pack refs that were already packed or are tags */ + if (!cb->all && !is_tag_ref && !(flags & REF_ISPACKED)) return 0; fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path); diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 16bdae4f23..f0c7e22b36 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -96,4 +96,13 @@ test_expect_success \ git-branch -d n/o/p && git-branch n' +test_expect_success 'pack, prune and repack' ' + git-tag foo && + git-pack-refs --all --prune && + git-show-ref >all-of-them && + git-pack-refs && + git-show-ref >again && + diff all-of-them again +' + test_done From fd73423f01361f112dbb9972ebce8eabae7dd8b1 Mon Sep 17 00:00:00 2001 From: Sam Vilain Date: Fri, 26 Jan 2007 12:41:23 +1300 Subject: [PATCH 04/47] contrib/emacs/vc-git.el: support vc-version-other-window Currently, the vc-git-checkout function uses `git checkout' to fetch a file from the git repository to the working copy. However, it is completely ignoring the input argument that specifies the destination file. `git-checkout' does not support specifying this, so we have to use `git-cat-file', capture the output in a buffer and then save it. Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index 3eb4bd19e9..65c4550069 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -53,6 +53,10 @@ (let ((name (file-relative-name file))) (eq 0 (apply #'call-process "git" nil (get-buffer "*Messages") nil (append args (list name)))))) +(defun vc-git--run-command-out (output &rest args) + "Run a git command, output to output." + (eq 0 (apply #'call-process "git" nil output nil (append args)))) + (defun vc-git-registered (file) "Check whether FILE is registered with git." (with-temp-buffer @@ -120,7 +124,28 @@ (vc-git--run-command file "commit" "-m" comment "--only" "--"))) (defun vc-git-checkout (file &optional editable rev destfile) - (vc-git--run-command file "checkout" (or rev "HEAD"))) + (if destfile + (let ((mybuff (get-buffer-create "vc-git-checkout-tmp"))) + (let ((rv + (vc-git--run-command-out + mybuff "cat-file" "blob" + (concat (or rev "HEAD") + ":" + (let ((output (vc-git--run-command-string + (file-relative-name file) + "ls-files" "--full-name"))) + (string-match "\\(.*\\)" output) + (match-string 1 output)) + ))) + ) + (if rv + (save-current-buffer + (set-buffer mybuff) + (set-visited-file-name destfile t) + (save-buffer) + ) + rv))) + (vc-git--run-command file "checkout" (or rev "HEAD")))) (defun vc-git-annotate-command (file buf &optional rev) ; FIXME: rev is ignored From cb280e107523e5263f390db715234700355a63b9 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 25 Jan 2007 19:05:01 -0800 Subject: [PATCH 05/47] Allow non-developer to clone, checkout and fetch more easily. The code that uses committer_info() in reflog can barf and die whenever it is asked to update a ref. And I do not think calling ignore_missing_committer_name() upfront like recent receive-pack did in the aplication is a reasonable workaround. What the patch does. - git_committer_info() takes one parameter. It used to be "if this is true, then die() if the name is not available due to bad GECOS, otherwise issue a warning once but leave the name empty". The reason was because we wanted to prevent bad commits from being made by git-commit-tree (and its callers). The value 0 is only used by "git var -l". Now it takes -1, 0 or 1. When set to -1, it does not complain but uses the pw->pw_name when name is not available. Existing 0 and 1 values mean the same thing as they used to mean before. 0 means issue warnings and leave it empty, 1 means barf and die. - ignore_missing_committer_name() and its existing caller (receive-pack, to set the reflog) have been removed. - git-format-patch, to come up with the phoney message ID when asked to thread, now passes -1 to git_committer_info(). This codepath uses only the e-mail part, ignoring the name. It used to barf and die. The other call in the same program when asked to add signed-off-by line based on committer identity still passes 1 to make sure it barfs instead of adding a bogus s-o-b line. - log_ref_write in refs.c, to come up with the name to record who initiated the ref update in the reflog, passes -1. It used to barf and die. The last change means that git-update-ref, git-branch, and commit walker backends can now be used in a repository with reflog by somebody who does not have the user identity required to make a commit. They all used to barf and die. I've run tests and all of them seem to pass, and also tried "git clone" as a user whose GECOS is empty -- git clone works again now (it was broken when reflog was enabled by default). But this definitely needs extra sets of eyeballs. Signed-off-by: Junio C Hamano --- builtin-log.c | 2 +- cache.h | 1 - ident.c | 28 +++++++++++----------------- receive-pack.c | 2 -- refs.c | 2 +- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index 503cd1e2be..56acc137f0 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -352,7 +352,7 @@ static void get_patch_ids(struct rev_info *rev, struct diff_options *options, co static void gen_message_id(char *dest, unsigned int length, char *base) { - const char *committer = git_committer_info(1); + const char *committer = git_committer_info(-1); const char *email_start = strrchr(committer, '<'); const char *email_end = strrchr(committer, '>'); if(!email_start || !email_end || email_start > email_end - 1) diff --git a/cache.h b/cache.h index 473197ded8..9486132ac5 100644 --- a/cache.h +++ b/cache.h @@ -320,7 +320,6 @@ void datestamp(char *buf, int bufsize); unsigned long approxidate(const char *); extern int setup_ident(void); -extern void ignore_missing_committer_name(void); extern const char *git_author_info(int); extern const char *git_committer_info(int); diff --git a/ident.c b/ident.c index 6ad8fedd60..f9677905e5 100644 --- a/ident.c +++ b/ident.c @@ -180,12 +180,21 @@ static const char *get_ident(const char *name, const char *email, email = git_default_email; if (!*name) { - if (name == git_default_name && env_hint) { + struct passwd *pw; + + if (0 <= error_on_no_name && + name == git_default_name && env_hint) { fprintf(stderr, env_hint, au_env, co_env); env_hint = NULL; /* warn only once, for "git-var -l" */ } - if (error_on_no_name) + if (0 < error_on_no_name) die("empty ident %s <%s> not allowed", name, email); + pw = getpwuid(getuid()); + if (!pw) + die("You don't exist. Go away!"); + strlcpy(git_default_name, pw->pw_name, + sizeof(git_default_name)); + name = git_default_name; } strcpy(date, git_default_date); @@ -218,18 +227,3 @@ const char *git_committer_info(int error_on_no_name) getenv("GIT_COMMITTER_DATE"), error_on_no_name); } - -void ignore_missing_committer_name() -{ - /* If we did not get a name from the user's gecos entry then - * git_default_name is empty; so instead load the username - * into it as a 'good enough for now' approximation of who - * this user is. - */ - if (!*git_default_name) { - struct passwd *pw = getpwuid(getuid()); - if (!pw) - die("You don't exist. Go away!"); - strlcpy(git_default_name, pw->pw_name, sizeof(git_default_name)); - } -} diff --git a/receive-pack.c b/receive-pack.c index 8b59b3227e..7d263262d3 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -430,8 +430,6 @@ int main(int argc, char **argv) die("attempt to push into a shallow repository"); setup_ident(); - /* don't die if gecos is empty */ - ignore_missing_committer_name(); git_config(receive_pack_config); if (0 <= transfer_unpack_limit) diff --git a/refs.c b/refs.c index 81173282fc..4323e9a41a 100644 --- a/refs.c +++ b/refs.c @@ -958,7 +958,7 @@ static int log_ref_write(struct ref_lock *lock, lock->log_file, strerror(errno)); } - committer = git_committer_info(1); + committer = git_committer_info(-1); if (msg) { maxlen = strlen(committer) + strlen(msg) + 2*40 + 5; logrec = xmalloc(maxlen); From e1b161161d253a9e7e4cf21cd2ab5b82a4b85273 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 25 Jan 2007 23:48:58 -0500 Subject: [PATCH 06/47] diffcore-pickaxe: fix infinite loop on zero-length needle The "contains" algorithm runs into an infinite loop if the needle string has zero length. The loop could be modified to handle this, but it makes more sense to simply have an empty needle return no matches. Thus, a command like git log -S produces no output. We place the check at the top of the function so that we get the same results with or without --pickaxe-regex. Note that until now, git log -S --pickaxe-regex would match everything, not nothing. Arguably, an empty pickaxe string should simply produce an error message; however, this is still a useful assertion to add to the algorithm at this layer of the code. Noticed by Bill Lear. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- diffcore-pickaxe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index de44adabf0..286919e714 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -14,6 +14,8 @@ static unsigned int contains(struct diff_filespec *one, const char *data; if (diff_populate_filespec(one, 0)) return 0; + if (!len) + return 0; sz = one->size; data = one->data; From ae9c6ffe3039fc4d0a89eb253800b3ca58830bb2 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 25 Jan 2007 21:50:49 -0800 Subject: [PATCH 07/47] parse-remote: do not barf on a remote shorthand without any refs to fetch. Signed-off-by: Junio C Hamano --- git-parse-remote.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 1122c8389d..7e87f2e06e 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -81,7 +81,14 @@ get_remote_default_refs_for_push () { # is to help prevent randomly "globbed" ref from being chosen as # a merge candidate expand_refs_wildcard () { + remote="$1" + shift first_one=yes + if test "$#" = 0 + then + echo empty + echo >&2 "Nothing specified for fetching with remote.$remote.fetch" + fi for ref do lref=${ref#'+'} @@ -132,7 +139,7 @@ canon_refs_list_for_fetch () { if test "$1" = "-d" then shift ; remote="$1" ; shift - set $(expand_refs_wildcard "$@") + set $(expand_refs_wildcard "$remote" "$@") is_explicit="$1" shift if test "$remote" = "$(get_default_remote)" From a9eefb3bfc66b7f5dba86ebf57b05e32c33eb9e5 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 25 Jan 2007 21:55:34 -0800 Subject: [PATCH 08/47] Add dangling objects tips. Signed-off-by: Junio C Hamano --- Documentation/howto/dangling-objects.txt | 109 +++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/howto/dangling-objects.txt diff --git a/Documentation/howto/dangling-objects.txt b/Documentation/howto/dangling-objects.txt new file mode 100644 index 0000000000..e82ddae3cf --- /dev/null +++ b/Documentation/howto/dangling-objects.txt @@ -0,0 +1,109 @@ +From: Linus Torvalds +Subject: Re: Question about fsck-objects output +Date: Thu, 25 Jan 2007 12:01:06 -0800 (PST) +Message-ID: +Archived-At: +Abstract: Linus describes what dangling objects are, when they + are left behind, and how to view their relationship with branch + heads in gitk + +On Thu, 25 Jan 2007, Larry Streepy wrote: + +> Sorry to ask such a basic question, but I can't quite decipher the output of +> fsck-objects. When I run it, I get this: +> +> git fsck-objects +> dangling commit 2213f6d4dd39ca8baebd0427723723e63208521b +> dangling commit f0d4e00196bd5ee54463e9ea7a0f0e8303da767f +> dangling blob 6a6d0b01b3e96d49a8f2c7addd4ef8c3bd1f5761 +> +> +> Even after a "repack -a -d" they still exist. The man page has a short +> explanation, but, at least for me, it wasn't fully enlightening. :-) +> +> The man page says that dangling commits could be "root" commits, but since my +> repo started as a clone of another repo, I don't see how I could have any root +> commits. Also, the page doesn't really describe what a dangling blob is. +> +> So, can someone explain what these artifacts are and if they are a problem +> that I should be worried about? + +The most common situation is that you've rebased a branch (or you have +pulled from somebody else who rebased a branch, like the "pu" branch in +the git.git archive itself). + +What happens is that the old head of the original branch still exists, as +does obviously everything it pointed to. The branch pointer itself just +doesn't, since you replaced it with another one. + +However, there are certainly other situations too that cause dangling +objects. For example, the "dangling blob" situation you have tends to be +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 not being pointed to by any commit/tree, so +it's now a dangling blob object. + +Similarly, when the "recursive" merge strategy runs, and finds that there +are criss-cross merges and thus more than one merge base (which is fairly +unusual, but it does happen), it will generate one temporary midway tree +(or possibly even more, if you had lots of criss-crossing merges and +more than two merge bases) as a temporary internal merge base, and again, +those are real objects, but the end result will not end up pointing to +them, so they end up "dangling" in your repository. + +Generally, dangling objects aren't anything to worry about. They can even +be very useful: if you screw something up, the dangling objects can be how +you recover your old tree (say, you did a rebase, and realized that you +really didn't want to - you can look at what dangling objects you have, +and decide to reset your head to some old dangling state). + +For commits, the most useful thing to do with dangling objects tends to be +to do a simple + + gitk --not --all + +which means exactly what it sounds like: it says that you want to see the +commit history that is described by the dangling commit(s), but you do NOT +want to see the history that is described by all your branches and tags +(which are the things you normally reach). That basically shows you in a +nice way what the danglign commit was (and notice that it might not be +just one commit: we only report the "tip of the line" as being dangling, +but there might be a whole deep and complex commit history that has gotten +dropped - rebasing will do that). + +For blobs and trees, you can't do the same, but you can examine them. You +can just do + + git show + +to show what the contents of the blob were (or, for a tree, basically what +the "ls" for that directory was), and that may give you some idea of what +the operation was that left that dangling object. + +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, leaving _some_ +of the new objects in the object database, but just dangling and useless. + +Anyway, once you are sure that you're not interested in any dangling +state, you can just prune all unreachable objects: + + git prune + +and they'll be gone. But you should only run "git prune" on a quiescent +repository - it's kind of like doing a filesystem fsck recovery: you don't +want to do that while the filesystem is mounted. + +(The same is true of "git-fsck-objects" itself, btw - but since +git-fsck-objects never actually *changes* the repository, it just reports +on what it found, git-fsck-objects itself is never "dangerous" to run. +Running it while somebody is actually changing the repository can cause +confusing and scary messages, but it won't actually do anything bad. In +contrast, running "git prune" while somebody is actively changing the +repository is a *BAD* idea). + + Linus + From df373ea99a1cf3056a72bad1d66f0e62f3b41c20 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 25 Jan 2007 22:14:45 -0800 Subject: [PATCH 09/47] show-branch -g: default to HEAD Signed-off-by: Junio C Hamano --- builtin-show-branch.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/builtin-show-branch.c b/builtin-show-branch.c index 536245e7d3..fa62e487b1 100644 --- a/builtin-show-branch.c +++ b/builtin-show-branch.c @@ -662,13 +662,13 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) } ac--; av++; - if (!!extra || !!reflog) { + if (extra || reflog) { /* "listing" mode is incompatible with * independent nor merge-base modes. */ if (independent || merge_base) usage(show_branch_usage); - if (!!reflog && ((0 < extra) || all_heads || all_remotes)) + if (reflog && ((0 < extra) || all_heads || all_remotes)) /* * Asking for --more in reflog mode does not * make sense. --list is Ok. @@ -682,15 +682,22 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) if (ac + all_heads + all_remotes == 0) all_heads = 1; - if (all_heads + all_remotes) - snarf_refs(all_heads, all_remotes); if (reflog) { unsigned char sha1[20]; char nth_desc[256]; char *ref; int base = 0; + + if (ac == 0) { + static const char *fake_av[2]; + fake_av[0] = "HEAD"; + fake_av[1] = NULL; + av = fake_av; + ac = 1; + } if (ac != 1) die("--reflog option needs one branch name"); + if (MAX_REVS < reflog) die("Only %d entries can be shown at one time.", MAX_REVS); @@ -735,6 +742,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) append_ref(nth_desc, sha1, 1); } } + else if (all_heads + all_remotes) + snarf_refs(all_heads, all_remotes); else { while (0 < ac) { append_one_rev(*av); From af67e91c39aff2d955e9c325c6c4e843d5faef60 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 25 Jan 2007 22:51:49 -0800 Subject: [PATCH 10/47] Documentation: pack-refs --all vs default behaviour Document the recommended way to prime a repository with tons of references with 'pack-refs --all -prune'. Signed-off-by: Junio C Hamano --- Documentation/git-pack-refs.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/git-pack-refs.txt b/Documentation/git-pack-refs.txt index 464269fbb9..a20fc7de40 100644 --- a/Documentation/git-pack-refs.txt +++ b/Documentation/git-pack-refs.txt @@ -29,12 +29,23 @@ file and used if found. Subsequent updates to branches always creates new file under `$GIT_DIR/refs` hierarchy. +A recommended practice to deal with a repository with too many +refs is to pack its refs with `--all --prune` once, and +occasionally run `git-pack-refs \--prune`. Tags are by +definition stationary and are not expected to change. Branch +heads will be packed with the initial `pack-refs --all`, but +only the currently active branch heads will become unpacked, +and next `pack-refs` (without `--all`) will leave them +unpacked. + + OPTIONS ------- \--all:: -The command by default packs all tags and leaves branch tips +The command by default packs all tags and refs that are already +packed, and leaves other refs alone. This is because branches are expected to be actively developed and packing their tips does not help performance. This option causes branch tips to be packed as well. Useful for From 007e2ba65902b484fc65a313e54594a009841740 Mon Sep 17 00:00:00 2001 From: Jason Riedy Date: Thu, 25 Jan 2007 13:11:40 -0800 Subject: [PATCH 11/47] Use inttypes.h rather than stdint.h. Older Solaris machines lack stdint.h but have inttypes.h. The standard has inttypes.h including stdint.h, so at worst this pollutes the namespace a bit. Signed-off-by: Jason Riedy Signed-off-by: Junio C Hamano --- git-compat-util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-compat-util.h b/git-compat-util.h index bf3ceb8027..c1bcb001a5 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -46,7 +46,7 @@ #include #include #include -#include +#include #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */ #include #define _ALL_SOURCE 1 From 8a8169c0398ff9996216381d7688c2ba2d007050 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 25 Jan 2007 12:40:03 -0500 Subject: [PATCH 12/47] Remove unnecessary found variable from describe. Junio added the found variable to enforce commit date order when two tags have the same distance from the requested commit. Except it is unnecessary as match_cnt is already used to record how many possible tags have been identified thus far. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- builtin-describe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builtin-describe.c b/builtin-describe.c index e7b8f95c81..4921eee9e2 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -101,7 +101,6 @@ static void describe(const char *arg, int last_one) struct possible_tag all_matches[MAX_TAGS]; unsigned int match_cnt = 0, annotated_cnt = 0, cur_match; unsigned long seen_commits = 0; - int found = 0; if (get_sha1(arg, sha1)) die("Not a valid object name %s", arg); @@ -137,7 +136,7 @@ static void describe(const char *arg, int last_one) t->name = n; t->depth = seen_commits - 1; t->flag_within = 1u << match_cnt; - t->found_order = found++; + t->found_order = match_cnt; c->object.flags |= t->flag_within; if (n->prio == 2) annotated_cnt++; From 8ac65937d032ad3e4bda1d7d6a8b924a65a01fb4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 02:26:04 -0800 Subject: [PATCH 13/47] Make sure we do not write bogus reflog entries. The file format dictates that entries are LF terminated so the message cannot have one in it. Chomp the message to make sure it only has a single line if necessary, while removing the leading whitespace. Signed-off-by: Junio C Hamano --- builtin-update-ref.c | 2 -- refs.c | 39 +++++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/builtin-update-ref.c b/builtin-update-ref.c index b34e5987dd..f2506fa976 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -23,8 +23,6 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) msg = argv[++i]; if (!*msg) die("Refusing to perform update with empty message."); - if (strchr(msg, '\n')) - die("Refusing to perform update with \\n in message."); continue; } if (!strcmp("-d", argv[i])) { diff --git a/refs.c b/refs.c index 4323e9a41a..0840b3bab8 100644 --- a/refs.c +++ b/refs.c @@ -925,6 +925,7 @@ static int log_ref_write(struct ref_lock *lock, { int logfd, written, oflags = O_APPEND | O_WRONLY; unsigned maxlen, len; + int msglen; char *logrec; const char *committer; @@ -958,24 +959,30 @@ static int log_ref_write(struct ref_lock *lock, lock->log_file, strerror(errno)); } - committer = git_committer_info(-1); + msglen = 0; if (msg) { - maxlen = strlen(committer) + strlen(msg) + 2*40 + 5; - logrec = xmalloc(maxlen); - len = snprintf(logrec, maxlen, "%s %s %s\t%s\n", - sha1_to_hex(lock->old_sha1), - sha1_to_hex(sha1), - committer, - msg); - } - else { - maxlen = strlen(committer) + 2*40 + 4; - logrec = xmalloc(maxlen); - len = snprintf(logrec, maxlen, "%s %s %s\n", - sha1_to_hex(lock->old_sha1), - sha1_to_hex(sha1), - committer); + /* clean up the message and make sure it is a single line */ + for ( ; *msg; msg++) + if (!isspace(*msg)) + break; + if (*msg) { + const char *ep = strchr(msg, '\n'); + if (ep) + msglen = ep - msg; + else + msglen = strlen(msg); + } } + + committer = git_committer_info(-1); + maxlen = strlen(committer) + msglen + 100; + logrec = xmalloc(maxlen); + len = sprintf(logrec, "%s %s %s\n", + sha1_to_hex(lock->old_sha1), + sha1_to_hex(sha1), + committer); + if (msglen) + len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1; written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1; free(logrec); close(logfd); From 7f9acb2a16473e5ba6d44231d2fc844ca8bb9817 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 15:09:02 -0800 Subject: [PATCH 14/47] git-merge: leave sensible reflog message when used as the first level UI. It used to throw potentially multi-line log message at reflog. Just record the heads that were given to be merged at the command line and the action. Revert the removal of the check in "git-update-ref -m" I made earlier which was only a work-around for this. Signed-off-by: Junio C Hamano --- builtin-update-ref.c | 2 ++ git-merge.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/builtin-update-ref.c b/builtin-update-ref.c index f2506fa976..b34e5987dd 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -23,6 +23,8 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) msg = argv[++i]; if (!*msg) die("Refusing to perform update with empty message."); + if (strchr(msg, '\n')) + die("Refusing to perform update with \\n in message."); continue; } if (!strcmp("-d", argv[i])) { diff --git a/git-merge.sh b/git-merge.sh index 7b590268ed..656869101a 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -7,7 +7,6 @@ USAGE='[-n] [--no-commit] [--squash] [-s ] [-m=] Date: Fri, 26 Jan 2007 11:57:50 +0100 Subject: [PATCH 15/47] vc-git.el: Take into account the destination name in vc-checkout. This is necessary for vc-version-other-window. Based on a patch by Sam Vilain . Currently, the vc-git-checkout function uses `git checkout' to fetch a file from the git repository to the working copy. However, it is completely ignoring the input argument that specifies the destination file. `git-checkout' does not support specifying this, so we have to use `git-cat-file', capture the output in a buffer and then save it. Signed-off-by: Alexandre Julliard Signed-off-by: Junio C Hamano --- contrib/emacs/vc-git.el | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el index 65c4550069..e456ab9712 100644 --- a/contrib/emacs/vc-git.el +++ b/contrib/emacs/vc-git.el @@ -53,10 +53,6 @@ (let ((name (file-relative-name file))) (eq 0 (apply #'call-process "git" nil (get-buffer "*Messages") nil (append args (list name)))))) -(defun vc-git--run-command-out (output &rest args) - "Run a git command, output to output." - (eq 0 (apply #'call-process "git" nil output nil (append args)))) - (defun vc-git-registered (file) "Check whether FILE is registered with git." (with-temp-buffer @@ -125,26 +121,14 @@ (defun vc-git-checkout (file &optional editable rev destfile) (if destfile - (let ((mybuff (get-buffer-create "vc-git-checkout-tmp"))) - (let ((rv - (vc-git--run-command-out - mybuff "cat-file" "blob" - (concat (or rev "HEAD") - ":" - (let ((output (vc-git--run-command-string - (file-relative-name file) - "ls-files" "--full-name"))) - (string-match "\\(.*\\)" output) - (match-string 1 output)) - ))) - ) - (if rv - (save-current-buffer - (set-buffer mybuff) - (set-visited-file-name destfile t) - (save-buffer) - ) - rv))) + (let ((fullname (substring + (vc-git--run-command-string file "ls-files" "-z" "--full-name" "--") + 0 -1)) + (coding-system-for-read 'no-conversion) + (coding-system-for-write 'no-conversion)) + (with-temp-file destfile + (eq 0 (call-process "git" nil t nil "cat-file" "blob" + (concat (or rev "HEAD") ":" fullname))))) (vc-git--run-command file "checkout" (or rev "HEAD")))) (defun vc-git-annotate-command (file buf &optional rev) From 8a56da29628997289aa8ec888ba85889962393e4 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 17:00:57 -0800 Subject: [PATCH 16/47] create_symref: check error return from open(). Signed-off-by: Junio C Hamano --- refs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index 0840b3bab8..12e46b8bbe 100644 --- a/refs.c +++ b/refs.c @@ -331,7 +331,11 @@ int create_symref(const char *ref_target, const char *refs_heads_master) return -1; } lockpath = mkpath("%s.lock", git_HEAD); - fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); + fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd < 0) { + error("Unable to open %s for writing", lockpath); + return -5; + } written = write_in_full(fd, ref, len); close(fd); if (written != len) { From d848804a895254583095b5c23ebb5d5f5a8891a3 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 17:39:03 -0800 Subject: [PATCH 17/47] write_in_full: size_t is unsigned. It received the return value from xwrite() in a size_t variable 'written' and expected comparison with 0 would catch an error from xwrite(). Signed-off-by: Junio C Hamano --- write_or_die.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/write_or_die.c b/write_or_die.c index 046e79d485..5c4bc8515a 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -23,7 +23,7 @@ int write_in_full(int fd, const void *buf, size_t count) ssize_t total = 0; while (count > 0) { - size_t written = xwrite(fd, p, count); + ssize_t written = xwrite(fd, p, count); if (written < 0) return -1; if (!written) { From eb3204dfbb71626f83a95d2ab24569226a39c601 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 11:50:06 -0500 Subject: [PATCH 18/47] fix suggested branch creation command when detaching head Doing: $ git checkout HEAD^ Generates the following message: |warning: you are not on ANY branch anymore. |If you meant to create a new branch from the commit, you need -b to |associate a new branch with the wanted checkout. Example: | git checkout -b HEAD^ Of course if the user does as told at this point the created branch won't be located at the expected commit. Reword this message a bit to avoid such confusion. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- git-checkout.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git-checkout.sh b/git-checkout.sh index c52f352f08..8500f51ea2 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -156,9 +156,9 @@ then if test -n "$oldbranch" then detach_warn="warning: you are not on ANY branch anymore. -If you meant to create a new branch from the commit, you need -b to -associate a new branch with the wanted checkout. Example: - git checkout -b $arg" +If you meant to create a new branch from this checkout, you may still do +so (now or later) by using -b with the checkout command again. Example: + git checkout -b " fi elif test -z "$oldbranch" && test -n "$branch" then From f127404c45eff139037834a6464b68fbe1798e16 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Fri, 26 Jan 2007 14:28:55 +0000 Subject: [PATCH 19/47] If abbrev is set to zero in git-describe, don't add the unique suffix When on a non-tag commit, git-describe normally outputs descriptions of the form v1.0.0-g1234567890 Some scripts (for example the update hook script) might just want to know the name of the nearest tag, so they then have to do x=$(git-describe HEAD | sed 's/-g*//') This is costly, but more importantly is fragile as it is relying on the output format of git-describe, which we would then have to maintain forever. This patch adds support for setting the --abbrev option to zero. In that case git-describe does as it always has, but outputs only the nearest found tag instead of a completely unique name. This means that scripts would not have to parse the output format and won't need changing if the git-describe suffix is ever changed. Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano --- builtin-describe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/builtin-describe.c b/builtin-describe.c index 4921eee9e2..f3ac2d5f89 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -188,8 +188,11 @@ static void describe(const char *arg, int last_one) sha1_to_hex(gave_up_on->object.sha1)); } } - printf("%s-g%s\n", all_matches[0].name->path, - find_unique_abbrev(cmit->object.sha1, abbrev)); + if (abbrev == 0) + printf("%s\n", all_matches[0].name->path ); + else + printf("%s-g%s\n", all_matches[0].name->path, + find_unique_abbrev(cmit->object.sha1, abbrev)); if (!last_one) clear_commit_marks(cmit, -1); @@ -212,7 +215,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) tags = 1; else if (!strncmp(arg, "--abbrev=", 9)) { abbrev = strtoul(arg + 9, NULL, 10); - if (abbrev < MINIMUM_ABBREV || 40 < abbrev) + if (abbrev != 0 && (abbrev < MINIMUM_ABBREV || 40 < abbrev)) abbrev = DEFAULT_ABBREV; } else if (!strncmp(arg, "--candidates=", 13)) { From d67778eccdf778f0fc252aaade8a47c23bfebbd6 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Fri, 26 Jan 2007 14:13:46 +0000 Subject: [PATCH 20/47] Allow the tag signing key to be specified in the config file I did this: $ git tag -s test-sign gpg: skipped "Andy Parkins ": secret key not available gpg: signing failed: secret key not available failed to sign the tag with GPG. The problem is that I have used the comment field in my key's UID definition. $ gpg --list-keys andy pub 1024D/4F712F6D 2003-08-14 uid Andy Parkins (Google) So when git-tag looks for "Andy Parkins "; obviously it's not going to be found. There shouldn't be a requirement that I use the same form of my name in my git repository and my gpg key - I might want to be formal (Andrew) in my gpg key and informal (Andy) in the repository. Further I might have multiple keys in my keyring, and might want to use one that doesn't match up with the address I use in commit messages. This patch adds a configuration entry "user.signingkey" which, if present, will be passed to the "-u" switch for gpg, allowing the tag signing key to be overridden. If the entry is not present, the fallback is the original method, which means existing behaviour will continue untouched. Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano --- Documentation/config.txt | 7 +++++++ Documentation/git-tag.txt | 10 ++++++++++ git-tag.sh | 6 ++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 3f2fa09a87..6ea7c76a6a 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -469,6 +469,13 @@ user.name:: Can be overridden by the 'GIT_AUTHOR_NAME' and 'GIT_COMMITTER_NAME' environment variables. See gitlink:git-commit-tree[1]. +user.signingkey:: + If gitlink:git-tag[1] is not selecting the key you want it to + automatically when creating a signed tag, you can override the + default selection with this variable. This option is passed + unchanged to gpg's --local-user parameter, so you may specify a key + using any method that gpg supports. + whatchanged.difftree:: The default gitlink:git-diff-tree[1] arguments to be used for gitlink:git-whatchanged[1]. diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 13c7aefbf3..3f01e0bfc5 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -70,6 +70,16 @@ OPTIONS Take the tag message from the given file. Use '-' to read the message from the standard input. +CONFIGURATION +------------- +By default, git-tag in sign-with-default mode (-s) will use your +committer identity (of the form "Your Name ") to +find a key. If you want to use a different default key, you can specify +it in the repository configuration as follows: + +[user] + signingkey = + Author ------ Written by Linus Torvalds , diff --git a/git-tag.sh b/git-tag.sh index 94499c9b36..988bf4c6a6 100755 --- a/git-tag.sh +++ b/git-tag.sh @@ -112,7 +112,9 @@ git-check-ref-format "tags/$name" || object=$(git-rev-parse --verify --default HEAD "$@") || exit 1 type=$(git-cat-file -t $object) || exit 1 tagger=$(git-var GIT_COMMITTER_IDENT) || exit 1 -: ${username:=$(expr "z$tagger" : 'z\(.*>\)')} + +keyid=$(git-repo-config user.signingkey) || + keyid=$(expr "z$tagger" : 'z\(.*>\)') trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0 @@ -139,7 +141,7 @@ if [ "$annotate" ]; then cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG if [ "$signed" ]; then - gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP && + gpg -bsa -u "$keyid" "$GIT_DIR"/TAG_TMP && cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP || die "failed to sign the tag with GPG." fi From 16507fcf0a9991976815972faa253d77804d6f35 Mon Sep 17 00:00:00 2001 From: Bill Lear Date: Sat, 27 Jan 2007 07:21:53 -0600 Subject: [PATCH 21/47] Document --check option to git diff. Signed-off-by: Bill Lear Signed-off-by: Junio C Hamano --- Documentation/SubmittingPatches | 3 ++- Documentation/diff-options.txt | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 41b76d8a4a..ce85d06c62 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -23,7 +23,8 @@ probably need to split up your commit to finer grained pieces. Oh, another thing. I am picky about whitespaces. Make sure your changes do not trigger errors with the sample pre-commit hook shipped -in templates/hooks--pre-commit. +in templates/hooks--pre-commit. To help ensure this does not happen, +run git diff --check on your changes before you commit. (2) Generate your patch using git tools out of your commits. diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index da1cc60e97..019a39f2bf 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -58,6 +58,10 @@ Turn off rename detection, even when the configuration file gives the default to do so. +--check:: + Warn if changes introduce trailing whitespace + or an indent that uses a space before a tab. + --full-index:: Instead of the first handful characters, show full object name of pre- and post-image blob on the "index" From 903b45fe1808f72e712a118bf115b9dc07d02420 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sat, 27 Jan 2007 22:40:36 -0500 Subject: [PATCH 22/47] git-log -g --pretty=oneline should display the reflog message In the context of reflog output the reflog message is more useful than the commit message's first line. When relevant the reflog message will contain that line anyway. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- log-tree.c | 7 ++++++- reflog-walk.c | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/log-tree.c b/log-tree.c index c0fa096327..d8ca36bbdd 100644 --- a/log-tree.c +++ b/log-tree.c @@ -224,9 +224,14 @@ void show_log(struct rev_info *opt, const char *sep) printf("%s", diff_get_color(opt->diffopt.color_diff, DIFF_RESET)); putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n'); - if (opt->reflog_info) + if (opt->reflog_info) { show_reflog_message(opt->reflog_info, opt->commit_format == CMIT_FMT_ONELINE);; + if (opt->commit_format == CMIT_FMT_ONELINE) { + printf("%s", sep); + return; + } + } } /* diff --git a/reflog-walk.c b/reflog-walk.c index 8e2cd2fcf6..82621601d6 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -233,7 +233,7 @@ void show_reflog_message(struct reflog_walk_info* info, int oneline) else printf("%d", commit_reflog->reflogs->nr - 2 - commit_reflog->recno); - printf("}: "); + printf("}: %s", info->message); } else { printf("Reflog: %s@{", commit_reflog->reflogs->ref); From 01754769ab9bf9ff2fe2b12590e7ee2c7c3448ca Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 28 Jan 2007 00:50:53 -0800 Subject: [PATCH 23/47] Don't force everybody to call setup_ident(). Back when only handful commands that created commit and tag were the only users of committer identity information, it made sense to explicitly call setup_ident() to pre-fill the default value from the gecos information. But it is much simpler for programs to make the call automatic when get_ident() is called these days, since many more programs want to use the information when updating the reflog. Signed-off-by: Junio C Hamano --- builtin-branch.c | 1 - builtin-commit-tree.c | 1 - builtin-log.c | 1 - builtin-update-ref.c | 1 - cache.h | 1 - fetch-pack.c | 1 - http-fetch.c | 1 - http-push.c | 1 - ident.c | 51 +++++++++++++++++++++++++++++-------------- local-fetch.c | 1 - receive-pack.c | 1 - ssh-fetch.c | 1 - var.c | 1 - 13 files changed, 35 insertions(+), 28 deletions(-) diff --git a/builtin-branch.c b/builtin-branch.c index 25ffa5491c..d60690bb08 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -394,7 +394,6 @@ int cmd_branch(int argc, const char **argv, const char *prefix) int kinds = REF_LOCAL_BRANCH; int i; - setup_ident(); git_config(git_branch_config); for (i = 1; i < argc; i++) { diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 0651e5927e..2a818a0a2c 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -94,7 +94,6 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) unsigned int size; int encoding_is_utf8; - setup_ident(); git_config(git_default_config); if (argc < 2) diff --git a/builtin-log.c b/builtin-log.c index 56acc137f0..982d871887 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -380,7 +380,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) char message_id[1024]; char ref_message_id[1024]; - setup_ident(); git_config(git_format_config); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; diff --git a/builtin-update-ref.c b/builtin-update-ref.c index b34e5987dd..1461937cb9 100644 --- a/builtin-update-ref.c +++ b/builtin-update-ref.c @@ -13,7 +13,6 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) int i, delete; delete = 0; - setup_ident(); git_config(git_default_config); for (i = 1; i < argc; i++) { diff --git a/cache.h b/cache.h index 9486132ac5..9873ee97d9 100644 --- a/cache.h +++ b/cache.h @@ -319,7 +319,6 @@ int parse_date(const char *date, char *buf, int bufsize); void datestamp(char *buf, int bufsize); unsigned long approxidate(const char *); -extern int setup_ident(void); extern const char *git_author_info(int); extern const char *git_committer_info(int); diff --git a/fetch-pack.c b/fetch-pack.c index 83a1d7b319..c787106764 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -670,7 +670,6 @@ int main(int argc, char **argv) struct stat st; setup_git_directory(); - setup_ident(); git_config(fetch_pack_config); if (0 <= transfer_unpack_limit) diff --git a/http-fetch.c b/http-fetch.c index 67dfb0a033..efd494a47f 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1003,7 +1003,6 @@ int main(int argc, const char **argv) int arg = 1; int rc = 0; - setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/http-push.c b/http-push.c index 0a15f53782..b128c0146c 100644 --- a/http-push.c +++ b/http-push.c @@ -2299,7 +2299,6 @@ int main(int argc, char **argv) struct ref *ref; setup_git_directory(); - setup_ident(); remote = xcalloc(sizeof(*remote), 1); diff --git a/ident.c b/ident.c index f9677905e5..6de7eeae4d 100644 --- a/ident.c +++ b/ident.c @@ -43,19 +43,13 @@ static void copy_gecos(struct passwd *w, char *name, int sz) } -int setup_ident(void) +static void copy_email(struct passwd *pw) { - int len; - struct passwd *pw = getpwuid(getuid()); - - if (!pw) - die("You don't exist. Go away!"); - - /* Get the name ("gecos") */ - copy_gecos(pw, git_default_name, sizeof(git_default_name)); - - /* Make up a fake email address (name + '@' + hostname [+ '.' + domainname]) */ - len = strlen(pw->pw_name); + /* + * Make up a fake email address + * (name + '@' + hostname [+ '.' + domainname]) + */ + int len = strlen(pw->pw_name); if (len > sizeof(git_default_email)/2) die("Your sysadmin must hate you!"); memcpy(git_default_email, pw->pw_name, len); @@ -68,13 +62,37 @@ int setup_ident(void) len = strlen(git_default_email); git_default_email[len++] = '.'; if (he && (domainname = strchr(he->h_name, '.'))) - strlcpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len); + strlcpy(git_default_email + len, domainname + 1, + sizeof(git_default_email) - len); else - strlcpy(git_default_email + len, "(none)", sizeof(git_default_email) - len); + strlcpy(git_default_email + len, "(none)", + sizeof(git_default_email) - len); } +} + +static void setup_ident(void) +{ + struct passwd *pw = NULL; + + /* Get the name ("gecos") */ + if (!git_default_name[0]) { + pw = getpwuid(getuid()); + if (!pw) + die("You don't exist. Go away!"); + copy_gecos(pw, git_default_name, sizeof(git_default_name)); + } + + if (!git_default_email[0]) { + if (!pw) + pw = getpwuid(getuid()); + if (!pw) + die("You don't exist. Go away!"); + copy_email(pw); + } + /* And set the default date */ - datestamp(git_default_date, sizeof(git_default_date)); - return 0; + if (!git_default_date[0]) + datestamp(git_default_date, sizeof(git_default_date)); } static int add_raw(char *buf, int size, int offset, const char *str) @@ -174,6 +192,7 @@ static const char *get_ident(const char *name, const char *email, char date[50]; int i; + setup_ident(); if (!name) name = git_default_name; if (!email) diff --git a/local-fetch.c b/local-fetch.c index cf99cb72dd..7cfe8b3587 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -210,7 +210,6 @@ int main(int argc, const char **argv) char **commit_id; int arg = 1; - setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/receive-pack.c b/receive-pack.c index 7d263262d3..7311c822dd 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -429,7 +429,6 @@ int main(int argc, char **argv) if (is_repository_shallow()) die("attempt to push into a shallow repository"); - setup_ident(); git_config(receive_pack_config); if (0 <= transfer_unpack_limit) diff --git a/ssh-fetch.c b/ssh-fetch.c index 4c172b6824..bdf51a7a14 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -124,7 +124,6 @@ int main(int argc, char **argv) prog = getenv("GIT_SSH_PUSH"); if (!prog) prog = "git-ssh-upload"; - setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/var.c b/var.c index 39977b949a..e585e59d31 100644 --- a/var.c +++ b/var.c @@ -56,7 +56,6 @@ int main(int argc, char **argv) } setup_git_directory(); - setup_ident(); val = NULL; if (strcmp(argv[1], "-l") == 0) { From 717d1462ba0ebc430775eccaae65eb9b8234eb32 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 28 Jan 2007 01:34:06 -0800 Subject: [PATCH 24/47] git-blame --incremental This adds --incremental option to help GUI porcelains to show the result from git-blame incrementally. The output gives the origin information in the same format as the porcelain format. The first line has commit object name, the line number of the first line in the group in the original file, the line number of that file in the final image, and number of lines in the group. Then subsequent lines show the metainformation for the commit when the commit is shown for the first time, except the filename information is always shown (we cannot even make it conditional to -C option as blame always follows the renaming of the file wholesale). Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- builtin-blame.c | 173 ++++++++++++++++++++++++++++++------------------ 1 file changed, 107 insertions(+), 66 deletions(-) diff --git a/builtin-blame.c b/builtin-blame.c index 4a1accf13c..54ab675624 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -13,6 +13,7 @@ #include "diff.h" #include "diffcore.h" #include "revision.h" +#include "quote.h" #include "xdiff-interface.h" static char blame_usage[] = @@ -27,6 +28,7 @@ static char blame_usage[] = " -p, --porcelain Show in a format designed for machine consumption\n" " -L n,m Process only line range n,m, counting from 1\n" " -M, -C Find line movements within and across files\n" +" --incremental Show blame entries as we find them, incrementally\n" " -S revs-file Use revisions from revs-file instead of calling git-rev-list\n"; static int longest_file; @@ -36,6 +38,7 @@ static int max_digits; static int max_score_digits; static int show_root; static int blank_boundary; +static int incremental; #ifndef DEBUG #define DEBUG 0 @@ -1069,72 +1072,6 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt) origin_decref(parent_origin[i]); } -static void assign_blame(struct scoreboard *sb, struct rev_info *revs, int opt) -{ - while (1) { - struct blame_entry *ent; - struct commit *commit; - struct origin *suspect = NULL; - - /* find one suspect to break down */ - for (ent = sb->ent; !suspect && ent; ent = ent->next) - if (!ent->guilty) - suspect = ent->suspect; - if (!suspect) - return; /* all done */ - - origin_incref(suspect); - commit = suspect->commit; - if (!commit->object.parsed) - parse_commit(commit); - if (!(commit->object.flags & UNINTERESTING) && - !(revs->max_age != -1 && commit->date < revs->max_age)) - pass_blame(sb, suspect, opt); - else { - commit->object.flags |= UNINTERESTING; - if (commit->object.parsed) - mark_parents_uninteresting(commit); - } - /* treat root commit as boundary */ - if (!commit->parents && !show_root) - commit->object.flags |= UNINTERESTING; - - /* Take responsibility for the remaining entries */ - for (ent = sb->ent; ent; ent = ent->next) - if (!cmp_suspect(ent->suspect, suspect)) - ent->guilty = 1; - origin_decref(suspect); - - if (DEBUG) /* sanity */ - sanity_check_refcnt(sb); - } -} - -static const char *format_time(unsigned long time, const char *tz_str, - int show_raw_time) -{ - static char time_buf[128]; - time_t t = time; - int minutes, tz; - struct tm *tm; - - if (show_raw_time) { - sprintf(time_buf, "%lu %s", time, tz_str); - return time_buf; - } - - tz = atoi(tz_str); - minutes = tz < 0 ? -tz : tz; - minutes = (minutes / 100)*60 + (minutes % 100); - minutes = tz < 0 ? -minutes : minutes; - t = time + minutes * 60; - tm = gmtime(&t); - - strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", tm); - strcat(time_buf, tz_str); - return time_buf; -} - struct commit_info { char *author; @@ -1245,6 +1182,105 @@ static void get_commit_info(struct commit *commit, summary_buf[len] = 0; } +static void found_guilty_entry(struct blame_entry *ent) +{ + if (ent->guilty) + return; + ent->guilty = 1; + if (incremental) { + struct origin *suspect = ent->suspect; + + printf("%s %d %d %d\n", + sha1_to_hex(suspect->commit->object.sha1), + ent->s_lno + 1, ent->lno + 1, ent->num_lines); + if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { + struct commit_info ci; + suspect->commit->object.flags |= METAINFO_SHOWN; + get_commit_info(suspect->commit, &ci, 1); + printf("author %s\n", ci.author); + printf("author-mail %s\n", ci.author_mail); + printf("author-time %lu\n", ci.author_time); + printf("author-tz %s\n", ci.author_tz); + printf("committer %s\n", ci.committer); + printf("committer-mail %s\n", ci.committer_mail); + printf("committer-time %lu\n", ci.committer_time); + printf("committer-tz %s\n", ci.committer_tz); + printf("summary %s\n", ci.summary); + if (suspect->commit->object.flags & UNINTERESTING) + printf("boundary\n"); + } + printf("filename "); + write_name_quoted(NULL, 0, suspect->path, 1, stdout); + putchar('\n'); + } +} + +static void assign_blame(struct scoreboard *sb, struct rev_info *revs, int opt) +{ + while (1) { + struct blame_entry *ent; + struct commit *commit; + struct origin *suspect = NULL; + + /* find one suspect to break down */ + for (ent = sb->ent; !suspect && ent; ent = ent->next) + if (!ent->guilty) + suspect = ent->suspect; + if (!suspect) + return; /* all done */ + + origin_incref(suspect); + commit = suspect->commit; + if (!commit->object.parsed) + parse_commit(commit); + if (!(commit->object.flags & UNINTERESTING) && + !(revs->max_age != -1 && commit->date < revs->max_age)) + pass_blame(sb, suspect, opt); + else { + commit->object.flags |= UNINTERESTING; + if (commit->object.parsed) + mark_parents_uninteresting(commit); + } + /* treat root commit as boundary */ + if (!commit->parents && !show_root) + commit->object.flags |= UNINTERESTING; + + /* Take responsibility for the remaining entries */ + for (ent = sb->ent; ent; ent = ent->next) + if (!cmp_suspect(ent->suspect, suspect)) + found_guilty_entry(ent); + origin_decref(suspect); + + if (DEBUG) /* sanity */ + sanity_check_refcnt(sb); + } +} + +static const char *format_time(unsigned long time, const char *tz_str, + int show_raw_time) +{ + static char time_buf[128]; + time_t t = time; + int minutes, tz; + struct tm *tm; + + if (show_raw_time) { + sprintf(time_buf, "%lu %s", time, tz_str); + return time_buf; + } + + tz = atoi(tz_str); + minutes = tz < 0 ? -tz : tz; + minutes = (minutes / 100)*60 + (minutes % 100); + minutes = tz < 0 ? -minutes : minutes; + t = time + minutes * 60; + tm = gmtime(&t); + + strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", tm); + strcat(time_buf, tz_str); + return time_buf; +} + #define OUTPUT_ANNOTATE_COMPAT 001 #define OUTPUT_LONG_OBJECT_NAME 002 #define OUTPUT_RAW_TIMESTAMP 004 @@ -1717,6 +1753,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix) die("More than one '-L n,m' option given"); bottomtop = arg; } + else if (!strcmp("--incremental", arg)) + incremental = 1; else if (!strcmp("--score-debug", arg)) output_option |= OUTPUT_SHOW_SCORE; else if (!strcmp("-f", arg) || @@ -1907,6 +1945,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix) assign_blame(&sb, &revs, opt); + if (incremental) + return 0; + coalesce(&sb); if (!(output_option & OUTPUT_PORCELAIN)) From 46e5e69d5f2e8ae87a29953531a3d1bd7cb0292f Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 28 Jan 2007 01:42:31 -0800 Subject: [PATCH 25/47] git-blame --porcelain: quote filename in c-style when needed. Otherwise a pathname that has funny characters such as LF would screw up the parsing programs of the output. Strictly speaking, this is not backward compatible, but the current output for pathnames that have embedded LF and such cannot be sanely parsed anyway, and pathnames that only use characters from the portable pathname character set won't be affected. Signed-off-by: Junio C Hamano --- builtin-blame.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/builtin-blame.c b/builtin-blame.c index 54ab675624..7a58ee303f 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -1182,6 +1182,13 @@ static void get_commit_info(struct commit *commit, summary_buf[len] = 0; } +static void write_filename_info(const char *path) +{ + printf("filename "); + write_name_quoted(NULL, 0, path, 1, stdout); + putchar('\n'); +} + static void found_guilty_entry(struct blame_entry *ent) { if (ent->guilty) @@ -1209,9 +1216,7 @@ static void found_guilty_entry(struct blame_entry *ent) if (suspect->commit->object.flags & UNINTERESTING) printf("boundary\n"); } - printf("filename "); - write_name_quoted(NULL, 0, suspect->path, 1, stdout); - putchar('\n'); + write_filename_info(suspect->path); } } @@ -1315,13 +1320,13 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent) printf("committer-mail %s\n", ci.committer_mail); printf("committer-time %lu\n", ci.committer_time); printf("committer-tz %s\n", ci.committer_tz); - printf("filename %s\n", suspect->path); + write_filename_info(suspect->path); printf("summary %s\n", ci.summary); if (suspect->commit->object.flags & UNINTERESTING) printf("boundary\n"); } else if (suspect->commit->object.flags & MORE_THAN_ONE_PATH) - printf("filename %s\n", suspect->path); + write_filename_info(suspect->path); cp = nth_line(sb, ent->lno); for (cnt = 0; cnt < ent->num_lines; cnt++) { From 237fb6ca7cbe45f88523ad367d0d703a039dff2d Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 25 Jan 2007 12:39:54 -0500 Subject: [PATCH 26/47] Teach git-describe to display distances from tags. If you get two different describes at different times from a non-rewinding branch and they both come up with the same tag name, you can tell which is the 'newer' one by distance. This is rather common in practice, so its incredibly useful. [jc: still needs documentation and fixups when traversal gives up early.] Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- builtin-describe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/builtin-describe.c b/builtin-describe.c index f3ac2d5f89..aedbc78dac 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -191,8 +191,9 @@ static void describe(const char *arg, int last_one) if (abbrev == 0) printf("%s\n", all_matches[0].name->path ); else - printf("%s-g%s\n", all_matches[0].name->path, - find_unique_abbrev(cmit->object.sha1, abbrev)); + printf("%s-%d-g%s\n", all_matches[0].name->path, + all_matches[0].depth, + find_unique_abbrev(cmit->object.sha1, abbrev)); if (!last_one) clear_commit_marks(cmit, -1); From 1891261ed3ed52022ae5322b4db338f9d5112909 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 23:24:07 -0800 Subject: [PATCH 27/47] Update describe documentation. Signed-off-by: Junio C Hamano --- Documentation/git-describe.txt | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index b87783cf09..47a583d3a6 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -14,8 +14,8 @@ DESCRIPTION ----------- The command finds the most recent tag that is reachable from a commit, and if the commit itself is pointed at by the tag, shows -the tag. Otherwise, it suffixes the tag name with abbreviated -object name of the commit. +the tag. Otherwise, it suffixes the tag name with the number of +additional commits and the abbreviated object name of the commit. OPTIONS @@ -52,12 +52,18 @@ EXAMPLES With something like git.git current tree, I get: [torvalds@g5 git]$ git-describe parent - v1.0.4-g2414721b + v1.0.4-14-g2414721 i.e. the current head of my "parent" branch is based on v1.0.4, -but since it has a few commits on top of that, it has added the -git hash of the thing to the end: "-g" + 8-char shorthand for -the commit `2414721b194453f058079d897d13c4e377f92dc6`. +but since it has a handful commits on top of that, +describe has added the number of additional commits ("14") and +an abbreviated object name for the commit itself ("2414721") +at the end. + +The number of additional commits is the number +of commits which would be displayed by "git log v1.0.4..parent". +The hash suffix is "-g" + 7-char abbreviation for the tip commit +of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`). Doing a "git-describe" on a tag-name will just show the tag name: @@ -68,10 +74,16 @@ With --all, the command can use branch heads as references, so the output shows the reference path as well: [torvalds@g5 git]$ git describe --all --abbrev=4 v1.0.5^2 - tags/v1.0.0-g975b + tags/v1.0.0-21-g975b [torvalds@g5 git]$ git describe --all HEAD^ - heads/lt/describe-g975b + heads/lt/describe-7-g975b + +With --abbrev set to 0, the command can be used to find the +closest tagname without any suffix: + + [torvalds@g5 git]$ git describe --abbrev=0 v1.0.5^2 + tags/v1.0.0 SEARCH STRATEGY --------------- @@ -97,7 +109,8 @@ will be the smallest number of commits possible. Author ------ Written by Linus Torvalds , but somewhat -butchered by Junio C Hamano +butchered by Junio C Hamano . Later significantly +updated by Shawn Pearce . Documentation -------------- From 1b600e659abc7e409c9d830e332d3cef01062c1c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sat, 27 Jan 2007 01:54:21 -0500 Subject: [PATCH 28/47] Compute accurate distances in git-describe before output. My prior change to git-describe attempts to print the distance between the input commit and the best matching tag, but this distance was usually only an estimate as we always aborted revision walking as soon as we overflowed the configured limit on the number of possible tags (as set by --candidates). Displaying an estimated distance is not very useful and can just be downright confusing. Most users (heck, most Git developers) don't immediately understand why this distance differs from the output of common tools such as `git rev-list | wc -l`. Even worse, the estimated distance could change in the future (including decreasing despite no rebase occuring) if we find more possible tags earlier on during traversal. (This could happen if more tags are merged into the branch between queries.) These factors basically make an estimated distance useless. Fortunately we are usually most of the way through an accurate distance computation by the time we abort (due to reaching the current --candidates limit). This means we can simply finish counting out the revisions still in our commit queue to present the accurate distance at the end. The number of commits remaining in the commit queue is probably less than the number of commits already traversed, so finishing out the count is not likely to take very long. This final distance will then always match the output of `git rev-list | wc -l`. We can easily reduce the total number of commits that need to be walked at the end by stopping as soon as all of the commits in the commit queue are flagged as being merged into the already selected best possible tag. If that's true then there are no remaining unseen commits which can contribute to our best possible tag's depth counter, so further traversal is useless. Basic testing on my Mac OS X system shows there is no noticable performance difference between this accurate distance counting version of git-describe and the prior version of git-describe, at least when run on git.git. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- builtin-describe.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/builtin-describe.c b/builtin-describe.c index aedbc78dac..bcc645622a 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -91,6 +91,39 @@ static int compare_pt(const void *a_, const void *b_) return 0; } +static unsigned long finish_depth_computation( + struct commit_list **list, + struct possible_tag *best) +{ + unsigned long seen_commits = 0; + while (*list) { + struct commit *c = pop_commit(list); + struct commit_list *parents = c->parents; + seen_commits++; + if (c->object.flags & best->flag_within) { + struct commit_list *a = *list; + while (a) { + struct commit *i = a->item; + if (!(i->object.flags & best->flag_within)) + break; + a = a->next; + } + if (!a) + break; + } else + best->depth++; + while (parents) { + struct commit *p = parents->item; + parse_commit(p); + if (!(p->object.flags & SEEN)) + insert_by_date(p, list); + p->object.flags |= c->object.flags; + parents = parents->next; + } + } + return seen_commits; +} + static void describe(const char *arg, int last_one) { unsigned char sha1[20]; @@ -166,12 +199,19 @@ static void describe(const char *arg, int last_one) parents = parents->next; } } - free_commit_list(list); if (!match_cnt) die("cannot describe '%s'", sha1_to_hex(cmit->object.sha1)); qsort(all_matches, match_cnt, sizeof(all_matches[0]), compare_pt); + + if (gave_up_on) { + insert_by_date(gave_up_on, &list); + seen_commits--; + } + seen_commits += finish_depth_computation(&list, &all_matches[0]); + free_commit_list(list); + if (debug) { for (cur_match = 0; cur_match < match_cnt; cur_match++) { struct possible_tag *t = &all_matches[cur_match]; From 9a13f0b71b887af42c3be854344f185c6dfa1d0d Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:05 -0500 Subject: [PATCH 29/47] make reflog filename independent from struct ref_lock This allows for ref_log_write() to be used in a more flexible way, and is needed for future changes. This is only code reorg with no behavior change. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- builtin-reflog.c | 10 ++++++---- refs.c | 40 ++++++++++++++++++++-------------------- refs.h | 1 - 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/builtin-reflog.c b/builtin-reflog.c index b443ed9ef6..b6612a90ed 100644 --- a/builtin-reflog.c +++ b/builtin-reflog.c @@ -242,7 +242,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, struct cmd_reflog_expire_cb *cmd = cb_data; struct expire_reflog_cb cb; struct ref_lock *lock; - char *newlog_path = NULL; + char *log_file, *newlog_path = NULL; int status = 0; if (strncmp(ref, "refs/", 5)) @@ -255,7 +255,8 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, lock = lock_ref_sha1(ref + 5, sha1); if (!lock) return error("cannot lock ref '%s'", ref); - if (!file_exists(lock->log_file)) + log_file = xstrdup(git_path("logs/%s", ref)); + if (!file_exists(log_file)) goto finish; if (!cmd->dry_run) { newlog_path = xstrdup(git_path("logs/%s.lock", ref)); @@ -271,13 +272,14 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, if (fclose(cb.newlog)) status |= error("%s: %s", strerror(errno), newlog_path); - if (rename(newlog_path, lock->log_file)) { + if (rename(newlog_path, log_file)) { status |= error("cannot rename %s to %s", - newlog_path, lock->log_file); + newlog_path, log_file); unlink(newlog_path); } } free(newlog_path); + free(log_file); unlock_ref(lock); return status; } diff --git a/refs.c b/refs.c index 12e46b8bbe..3b295f3806 100644 --- a/refs.c +++ b/refs.c @@ -680,7 +680,6 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char lock->lk = xcalloc(1, sizeof(struct lock_file)); lock->ref_name = xstrdup(ref); - lock->log_file = xstrdup(git_path("logs/%s", ref)); ref_file = git_path("%s", ref); lock->force_write = lstat(ref_file, &st) && errno == ENOENT; @@ -776,10 +775,10 @@ int delete_ref(const char *refname, unsigned char *sha1) */ ret |= repack_without_ref(refname); - err = unlink(lock->log_file); + err = unlink(git_path("logs/%s", lock->ref_name)); if (err && errno != ENOENT) fprintf(stderr, "warning: unlink(%s) failed: %s", - lock->log_file, strerror(errno)); + git_path("logs/%s", lock->ref_name), strerror(errno)); invalidate_cached_refs(); unlock_ref(lock); return ret; @@ -920,47 +919,48 @@ void unlock_ref(struct ref_lock *lock) rollback_lock_file(lock->lk); } free(lock->ref_name); - free(lock->log_file); free(lock); } -static int log_ref_write(struct ref_lock *lock, - const unsigned char *sha1, const char *msg) +static int log_ref_write(const char *ref_name, const unsigned char *old_sha1, + const unsigned char *new_sha1, const char *msg) { int logfd, written, oflags = O_APPEND | O_WRONLY; unsigned maxlen, len; int msglen; - char *logrec; + char *log_file, *logrec; const char *committer; if (log_all_ref_updates < 0) log_all_ref_updates = !is_bare_repository(); + log_file = git_path("logs/%s", ref_name); + if (log_all_ref_updates && - (!strncmp(lock->ref_name, "refs/heads/", 11) || - !strncmp(lock->ref_name, "refs/remotes/", 13))) { - if (safe_create_leading_directories(lock->log_file) < 0) + (!strncmp(ref_name, "refs/heads/", 11) || + !strncmp(ref_name, "refs/remotes/", 13))) { + if (safe_create_leading_directories(log_file) < 0) return error("unable to create directory for %s", - lock->log_file); + log_file); oflags |= O_CREAT; } - logfd = open(lock->log_file, oflags, 0666); + logfd = open(log_file, oflags, 0666); if (logfd < 0) { if (!(oflags & O_CREAT) && errno == ENOENT) return 0; if ((oflags & O_CREAT) && errno == EISDIR) { - if (remove_empty_directories(lock->log_file)) { + if (remove_empty_directories(log_file)) { return error("There are still logs under '%s'", - lock->log_file); + log_file); } - logfd = open(lock->log_file, oflags, 0666); + logfd = open(log_file, oflags, 0666); } if (logfd < 0) return error("Unable to append to %s: %s", - lock->log_file, strerror(errno)); + log_file, strerror(errno)); } msglen = 0; @@ -982,8 +982,8 @@ static int log_ref_write(struct ref_lock *lock, maxlen = strlen(committer) + msglen + 100; logrec = xmalloc(maxlen); len = sprintf(logrec, "%s %s %s\n", - sha1_to_hex(lock->old_sha1), - sha1_to_hex(sha1), + sha1_to_hex(old_sha1), + sha1_to_hex(new_sha1), committer); if (msglen) len += sprintf(logrec + len - 1, "\t%.*s\n", msglen, msg) - 1; @@ -991,7 +991,7 @@ static int log_ref_write(struct ref_lock *lock, free(logrec); close(logfd); if (written != len) - return error("Unable to append to %s", lock->log_file); + return error("Unable to append to %s", log_file); return 0; } @@ -1014,7 +1014,7 @@ int write_ref_sha1(struct ref_lock *lock, return -1; } invalidate_cached_refs(); - if (log_ref_write(lock, sha1, logmsg) < 0) { + if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0) { unlock_ref(lock); return -1; } diff --git a/refs.h b/refs.h index 33450f13e7..2d2ba149ab 100644 --- a/refs.h +++ b/refs.h @@ -3,7 +3,6 @@ struct ref_lock { char *ref_name; - char *log_file; struct lock_file *lk; unsigned char old_sha1[20]; int lock_fd; From 1655707c9ec56847945854f8645ed64f74159e99 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:06 -0500 Subject: [PATCH 30/47] lock_ref_sha1_basic(): remember the original name of a ref when resolving it A ref might be pointing to another ref but only the name of the last ref is remembered. Let's remember about the first name as well. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- refs.c | 2 ++ refs.h | 1 + 2 files changed, 3 insertions(+) diff --git a/refs.c b/refs.c index 3b295f3806..bd76ea65a9 100644 --- a/refs.c +++ b/refs.c @@ -680,6 +680,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char lock->lk = xcalloc(1, sizeof(struct lock_file)); lock->ref_name = xstrdup(ref); + lock->orig_ref_name = xstrdup(orig_ref); ref_file = git_path("%s", ref); lock->force_write = lstat(ref_file, &st) && errno == ENOENT; @@ -919,6 +920,7 @@ void unlock_ref(struct ref_lock *lock) rollback_lock_file(lock->lk); } free(lock->ref_name); + free(lock->orig_ref_name); free(lock); } diff --git a/refs.h b/refs.h index 2d2ba149ab..94a58b41fb 100644 --- a/refs.h +++ b/refs.h @@ -3,6 +3,7 @@ struct ref_lock { char *ref_name; + char *orig_ref_name; struct lock_file *lk; unsigned char old_sha1[20]; int lock_fd; From bd104db164d7f2a714aa0f1cdf89fd89fee6c00a Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:07 -0500 Subject: [PATCH 31/47] enable separate reflog for HEAD If HEAD is tied to a branch then both logs/HEAD and logs/heads/ are updated. This is also true for any symbolic refs in general, but only HEAD will see its reflog created automatically. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- refs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/refs.c b/refs.c index bd76ea65a9..5b2ca086aa 100644 --- a/refs.c +++ b/refs.c @@ -940,7 +940,8 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1, if (log_all_ref_updates && (!strncmp(ref_name, "refs/heads/", 11) || - !strncmp(ref_name, "refs/remotes/", 13))) { + !strncmp(ref_name, "refs/remotes/", 13) || + !strcmp(ref_name, "HEAD"))) { if (safe_create_leading_directories(log_file) < 0) return error("unable to create directory for %s", log_file); @@ -1016,7 +1017,9 @@ int write_ref_sha1(struct ref_lock *lock, return -1; } invalidate_cached_refs(); - if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0) { + if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0 || + (strcmp(lock->ref_name, lock->orig_ref_name) && + log_ref_write(lock->orig_ref_name, lock->old_sha1, sha1, logmsg) < 0)) { unlock_ref(lock); return -1; } From e1dde3d06c7caa242dd4b419aebb9a9b7fee2d48 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:08 -0500 Subject: [PATCH 32/47] add reflog entries for HEAD when detached Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- git-checkout.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/git-checkout.sh b/git-checkout.sh index 8500f51ea2..ac378cdb1e 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -259,8 +259,9 @@ if [ "$?" -eq 0 ]; then # git update-ref --detach HEAD $new # or something like that... # - echo "$detached" >"$GIT_DIR/HEAD.new" && - mv "$GIT_DIR/HEAD.new" "$GIT_DIR/HEAD" || + git-rev-parse HEAD >"$GIT_DIR/HEAD.new" && + mv "$GIT_DIR/HEAD.new" "$GIT_DIR/HEAD" && + git-update-ref -m "checkout: moving to $arg" HEAD "$detached" || die "Cannot detach HEAD" if test -n "$detach_warn" then From 41b625b047ad5c537ca312d2f07c86bdd783a7b0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:09 -0500 Subject: [PATCH 33/47] move create_symref() past log_ref_write() This doesn't change the code at all. It is done to make the next patch more obvious. Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- refs.c | 94 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/refs.c b/refs.c index 5b2ca086aa..ec6fe29ebb 100644 --- a/refs.c +++ b/refs.c @@ -309,53 +309,6 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * return ref; } -int create_symref(const char *ref_target, const char *refs_heads_master) -{ - const char *lockpath; - char ref[1000]; - int fd, len, written; - const char *git_HEAD = git_path("%s", ref_target); - -#ifndef NO_SYMLINK_HEAD - if (prefer_symlink_refs) { - unlink(git_HEAD); - if (!symlink(refs_heads_master, git_HEAD)) - return 0; - fprintf(stderr, "no symlink - falling back to symbolic ref\n"); - } -#endif - - len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); - if (sizeof(ref) <= len) { - error("refname too long: %s", refs_heads_master); - return -1; - } - lockpath = mkpath("%s.lock", git_HEAD); - fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); - if (fd < 0) { - error("Unable to open %s for writing", lockpath); - return -5; - } - written = write_in_full(fd, ref, len); - close(fd); - if (written != len) { - unlink(lockpath); - error("Unable to write to %s", lockpath); - return -2; - } - if (rename(lockpath, git_HEAD) < 0) { - unlink(lockpath); - error("Unable to create %s", git_HEAD); - return -3; - } - if (adjust_shared_perm(git_HEAD)) { - unlink(lockpath); - error("Unable to fix permissions on %s", lockpath); - return -4; - } - return 0; -} - int read_ref(const char *ref, unsigned char *sha1) { if (resolve_ref(ref, sha1, 1, NULL)) @@ -1033,6 +986,53 @@ int write_ref_sha1(struct ref_lock *lock, return 0; } +int create_symref(const char *ref_target, const char *refs_heads_master) +{ + const char *lockpath; + char ref[1000]; + int fd, len, written; + const char *git_HEAD = git_path("%s", ref_target); + +#ifndef NO_SYMLINK_HEAD + if (prefer_symlink_refs) { + unlink(git_HEAD); + if (!symlink(refs_heads_master, git_HEAD)) + return 0; + fprintf(stderr, "no symlink - falling back to symbolic ref\n"); + } +#endif + + len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); + if (sizeof(ref) <= len) { + error("refname too long: %s", refs_heads_master); + return -1; + } + lockpath = mkpath("%s.lock", git_HEAD); + fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd < 0) { + error("Unable to open %s for writing", lockpath); + return -5; + } + written = write_in_full(fd, ref, len); + close(fd); + if (written != len) { + unlink(lockpath); + error("Unable to write to %s", lockpath); + return -2; + } + if (rename(lockpath, git_HEAD) < 0) { + unlink(lockpath); + error("Unable to create %s", git_HEAD); + return -3; + } + if (adjust_shared_perm(git_HEAD)) { + unlink(lockpath); + error("Unable to fix permissions on %s", lockpath); + return -4; + } + return 0; +} + static char *ref_msg(const char *line, const char *endp) { const char *ep; From 8b5157e40718a2ee1d645c342d93df4e66335479 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:10 -0500 Subject: [PATCH 34/47] add logref support to git-symbolic-ref Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- Documentation/git-symbolic-ref.txt | 6 +++++- builtin-branch.c | 3 ++- builtin-init-db.c | 2 +- builtin-symbolic-ref.c | 16 ++++++++++++++-- cache.h | 2 +- refs.c | 14 ++++++++++++-- 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt index f93b79a85e..a88f722860 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.txt @@ -7,7 +7,7 @@ git-symbolic-ref - Read and modify symbolic refs SYNOPSIS -------- -'git-symbolic-ref' [-q] [] +'git-symbolic-ref' [-q] [-m ] [] DESCRIPTION ----------- @@ -31,6 +31,10 @@ OPTIONS symbolic ref but a detached HEAD; instead exit with non-zero status silently. +-m:: + Update the reflog for with . This is valid only + when creating or updating a symbolic ref. + NOTES ----- In the past, `.git/HEAD` was a symbolic link pointing at diff --git a/builtin-branch.c b/builtin-branch.c index d60690bb08..76f174fd89 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -381,7 +381,8 @@ static void rename_branch(const char *oldname, const char *newname, int force) if (rename_ref(oldref, newref, logmsg)) die("Branch rename failed"); - if (!strcmp(oldname, head) && create_symref("HEAD", newref)) + /* no need to pass logmsg here as HEAD didn't really move */ + if (!strcmp(oldname, head) && create_symref("HEAD", newref, NULL)) die("Branch renamed to %s, but HEAD is not updated!", newname); } diff --git a/builtin-init-db.c b/builtin-init-db.c index 1865489381..12e43d0db4 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -231,7 +231,7 @@ static int create_default_files(const char *git_dir, const char *template_path) strcpy(path + len, "HEAD"); reinit = !read_ref("HEAD", sha1); if (!reinit) { - if (create_symref("HEAD", "refs/heads/master") < 0) + if (create_symref("HEAD", "refs/heads/master", NULL) < 0) exit(1); } diff --git a/builtin-symbolic-ref.c b/builtin-symbolic-ref.c index 227c9d4a62..d41b40640b 100644 --- a/builtin-symbolic-ref.c +++ b/builtin-symbolic-ref.c @@ -3,7 +3,7 @@ #include "refs.h" static const char git_symbolic_ref_usage[] = -"git-symbolic-ref [-q] name [ref]"; +"git-symbolic-ref [-q] [-m ] name [ref]"; static void check_symref(const char *HEAD, int quiet) { @@ -25,6 +25,7 @@ static void check_symref(const char *HEAD, int quiet) int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) { int quiet = 0; + const char *msg = NULL; git_config(git_default_config); @@ -34,6 +35,17 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) break; else if (!strcmp("-q", arg)) quiet = 1; + else if (!strcmp("-m", arg)) { + argc--; + argv++; + if (argc <= 1) + break; + msg = argv[1]; + if (!*msg) + die("Refusing to perform update with empty message"); + if (strchr(msg, '\n')) + die("Refusing to perform update with \\n in message"); + } else if (!strcmp("--", arg)) { argc--; argv++; @@ -50,7 +62,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) check_symref(argv[1], quiet); break; case 3: - create_symref(argv[1], argv[2]); + create_symref(argv[1], argv[2], msg); break; default: usage(git_symbolic_ref_usage); diff --git a/cache.h b/cache.h index 9873ee97d9..201704bacf 100644 --- a/cache.h +++ b/cache.h @@ -302,7 +302,7 @@ extern int read_ref(const char *filename, unsigned char *sha1); extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *); extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); -extern int create_symref(const char *ref, const char *refs_heads_master); +extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg); extern int validate_headref(const char *ref); extern int base_name_compare(const char *name1, int len1, int mode1, const char *name2, int len2, int mode2); diff --git a/refs.c b/refs.c index ec6fe29ebb..591318501f 100644 --- a/refs.c +++ b/refs.c @@ -986,18 +986,23 @@ int write_ref_sha1(struct ref_lock *lock, return 0; } -int create_symref(const char *ref_target, const char *refs_heads_master) +int create_symref(const char *ref_target, const char *refs_heads_master, + const char *logmsg) { const char *lockpath; char ref[1000]; int fd, len, written; const char *git_HEAD = git_path("%s", ref_target); + unsigned char old_sha1[20], new_sha1[20]; + + if (logmsg && read_ref(ref_target, old_sha1)) + hashclr(old_sha1); #ifndef NO_SYMLINK_HEAD if (prefer_symlink_refs) { unlink(git_HEAD); if (!symlink(refs_heads_master, git_HEAD)) - return 0; + goto done; fprintf(stderr, "no symlink - falling back to symbolic ref\n"); } #endif @@ -1030,6 +1035,11 @@ int create_symref(const char *ref_target, const char *refs_heads_master) error("Unable to fix permissions on %s", lockpath); return -4; } + + done: + if (logmsg && !read_ref(refs_heads_master, new_sha1)) + log_ref_write(ref_target, old_sha1, new_sha1, logmsg); + return 0; } From 47fc52e2876ed3a54cd4b77e0b0c4875fa3317b8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 26 Jan 2007 17:49:00 -0800 Subject: [PATCH 35/47] create_symref(): do not assume pathname from git_path() persists long enough Being lazy to rely on the cycling N buffers mkpath() and friends return is nice in general, but it makes it too easy to introduce new bugs that are "mysterious". Introduction of read_ref() in create_symref() after calling git_path() to get the git_HEAD value (i.e. the path to create a new symref at) consumed more than the available buffers and broke a later call to mkpath() that derives lockpath from it. Signed-off-by: Junio C Hamano --- refs.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/refs.c b/refs.c index 591318501f..4a523086e3 100644 --- a/refs.c +++ b/refs.c @@ -992,7 +992,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master, const char *lockpath; char ref[1000]; int fd, len, written; - const char *git_HEAD = git_path("%s", ref_target); + char *git_HEAD = xstrdup(git_path("%s", ref_target)); unsigned char old_sha1[20], new_sha1[20]; if (logmsg && read_ref(ref_target, old_sha1)) @@ -1010,36 +1010,38 @@ int create_symref(const char *ref_target, const char *refs_heads_master, len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); if (sizeof(ref) <= len) { error("refname too long: %s", refs_heads_master); - return -1; + goto error_free_return; } lockpath = mkpath("%s.lock", git_HEAD); fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); if (fd < 0) { error("Unable to open %s for writing", lockpath); - return -5; + goto error_free_return; } written = write_in_full(fd, ref, len); close(fd); if (written != len) { - unlink(lockpath); error("Unable to write to %s", lockpath); - return -2; + goto error_unlink_return; } if (rename(lockpath, git_HEAD) < 0) { - unlink(lockpath); error("Unable to create %s", git_HEAD); - return -3; + goto error_unlink_return; } if (adjust_shared_perm(git_HEAD)) { - unlink(lockpath); error("Unable to fix permissions on %s", lockpath); - return -4; + error_unlink_return: + unlink(lockpath); + error_free_return: + free(git_HEAD); + return -1; } done: if (logmsg && !read_ref(refs_heads_master, new_sha1)) log_ref_write(ref_target, old_sha1, new_sha1, logmsg); + free(git_HEAD); return 0; } From a7e4fbf990290f955da1319ab605a59f85d3c3e2 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 26 Jan 2007 17:26:11 -0500 Subject: [PATCH 36/47] add reflog when moving HEAD to a new branch Signed-off-by: Nicolas Pitre Signed-off-by: Junio C Hamano --- git-checkout.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git-checkout.sh b/git-checkout.sh index ac378cdb1e..1349e77f32 100755 --- a/git-checkout.sh +++ b/git-checkout.sh @@ -250,7 +250,7 @@ if [ "$?" -eq 0 ]; then fi if test -n "$branch" then - GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD "refs/heads/$branch" + GIT_DIR="$GIT_DIR" git-symbolic-ref -m "checkout: moving to $branch" HEAD "refs/heads/$branch" elif test -n "$detached" then # NEEDSWORK: we would want a command to detach the HEAD From 4f0219a4c76a2ce963cf355f90f18c9c59036bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=1B=2CAi=1B=28B=20Scharfe?= Date: Sun, 28 Jan 2007 15:25:55 +0100 Subject: [PATCH 37/47] git-blame --incremental: don't use pager Starting a pager defeats the purpose of the incremental output mode. This changes git-blame to only paginate if --incremental was not given. git -p blame --incremental still starts the pager, though. Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano --- builtin-blame.c | 3 +++ git.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/builtin-blame.c b/builtin-blame.c index 7a58ee303f..02bda5e196 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -1780,6 +1780,9 @@ int cmd_blame(int argc, const char **argv, const char *prefix) argv[unk++] = arg; } + if (!incremental) + setup_pager(); + if (!blame_move_score) blame_move_score = BLAME_DEFAULT_MOVE_SCORE; if (!blame_copy_score) diff --git a/git.c b/git.c index 530e99fe64..e9febc389a 100644 --- a/git.c +++ b/git.c @@ -217,7 +217,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "annotate", cmd_annotate, USE_PAGER }, { "apply", cmd_apply }, { "archive", cmd_archive }, - { "blame", cmd_blame, RUN_SETUP | USE_PAGER }, + { "blame", cmd_blame, RUN_SETUP }, { "branch", cmd_branch, RUN_SETUP }, { "cat-file", cmd_cat_file, RUN_SETUP }, { "checkout-index", cmd_checkout_index, RUN_SETUP }, From c3e821c6366571ee6a2775977340d8935a1ce143 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 28 Jan 2007 14:55:03 +0000 Subject: [PATCH 38/47] wt-status: Actually accept `color.status.BLAH' configuration variables. A stupid typo stopped this from working. Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano --- wt-status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wt-status.c b/wt-status.c index b7250e4310..5567868008 100644 --- a/wt-status.c +++ b/wt-status.c @@ -351,7 +351,7 @@ int git_status_config(const char *k, const char *v) wt_status_use_color = git_config_colorbool(k, v); return 0; } - if (!strncmp(k, "status.color.", 13) || !strncmp(k, "color.status", 13)) { + if (!strncmp(k, "status.color.", 13) || !strncmp(k, "color.status.", 13)) { int slot = parse_status_slot(k, 13); color_parse(v, k, wt_status_colors[slot]); } From 4f193f20a3d1884cc7b6c2a662783a3df8fe5d9b Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 28 Jan 2007 15:17:36 +0000 Subject: [PATCH 39/47] Documentation/config.txt: Fix documentation of colour config tweaks. * The description of valid colour specifications was rather incomplete, so fix it so that it actually describes colour specs as accepted by color_parse(). * The list of colour items allowed in color.diff.BLAH was missing the `commit' and `whitespace' entries. Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano --- Documentation/config.txt | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 6ea7c76a6a..ebda2e0f61 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -250,10 +250,15 @@ color.branch.:: Use customized color for branch coloration. `` is one of `current` (the current branch), `local` (a local branch), `remote` (a tracking branch in refs/remotes/), `plain` (other - refs), or `reset` (the normal terminal color). The value for - these configuration variables can be one of: `normal`, `bold`, - `dim`, `ul`, `blink`, `reverse`, `reset`, `black`, `red`, - `green`, `yellow`, `blue`, `magenta`, `cyan`, or `white`. + refs). ++ +The value for these configuration variables is a list of colors (at most +two) and attributes (at most one), separated by spaces. The colors +accepted are `normal`, `black`, `red`, `green`, `yellow`, `blue`, +`magenta`, `cyan` and `white`; the attributes are `bold`, `dim`, `ul`, +`blink` and `reverse`. The first color given is the foreground; the +second is the background. The position of the attribute, if any, +doesn't matter. color.diff:: When true (or `always`), always use colors in patch. @@ -261,12 +266,13 @@ color.diff:: colors only when the output is to the terminal. color.diff.:: - Use customized color for diff colorization. `` - specifies which part of the patch to use the specified - color, and is one of `plain` (context text), `meta` - (metainformation), `frag` (hunk header), `old` (removed - lines), or `new` (added lines). The values of these - variables may be specified as in color.branch.. + Use customized color for diff colorization. `` specifies + which part of the patch to use the specified color, and is one + of `plain` (context text), `meta` (metainformation), `frag` + (hunk header), `old` (removed lines), `new` (added lines), + `commit` (commit headers), or `whitespace` (highlighting dubious + whitespace). The values of these variables may be specified as + in color.branch.. color.pager:: A boolean to enable/disable colored output when the pager is in From 57e7a0a49496fa3c2b2514b6a23ad661ecb428a6 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 28 Jan 2007 12:21:53 -0800 Subject: [PATCH 40/47] Document 'git-blame --incremental' Signed-off-by: Junio C Hamano --- Documentation/git-blame.txt | 47 ++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index 5dd8e36bbd..0ee887d73c 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -8,7 +8,7 @@ git-blame - Show what revision and author last modified each line of a file SYNOPSIS -------- [verse] -'git-blame' [-c] [-l] [-t] [-f] [-n] [-p] [-L n,m] [-S ] +'git-blame' [-c] [-l] [-t] [-f] [-n] [-p] [--incremental] [-L n,m] [-S ] [-M] [-C] [-C] [--since=] [] [--] DESCRIPTION @@ -63,6 +63,10 @@ OPTIONS -p, --porcelain:: Show in a format designed for machine consumption. +--incremental:: + Show the result incrementally in a format designed for + machine consumption. + -M:: Detect moving lines in the file as well. When a commit moves a block of lines in a file (e.g. the original file @@ -158,6 +162,47 @@ parents, using `commit{caret}!` notation: git blame -C -C -f $commit^! -- foo +INCREMENTAL OUTPUT +------------------ + +When called with `--incremental` option, the command outputs the +result as it is built. The output generally will talk about +lines touched by more recent commits first (i.e. the lines will +be annotated out of order) and is meant to be used by +interactive viewers. + +The output format is similar to the Porcelain format, but it +does not contain the actual lines from the file that is being +annotated. + +. Each blame entry always starts with a line of: + + <40-byte hex sha1> ++ +Line numbers count from 1. + +. The first time that commit shows up in the stream, it has various + other information about it printed out with a one-word tag at the + beginning of each line about that "extended commit info" (author, + email, committer, dates, summary etc). + +. Unlike Porcelain format, the filename information is always + given and terminates the entry: + + "filename" ++ +and thus it's really quite easy to parse for some line- and word-oriented +parser (which should be quite natural for most scripting languages). ++ +[NOTE] +For people who do parsing: to make it more robust, just ignore any +lines in between the first and last one ("" and "filename" lines) +where you don't recognize the tag-words (or care about that particular +one) at the beginning of the "extended information" lines. That way, if +there is ever added information (like the commit encoding or extended +commit commentary), a blame viewer won't ever care. + + SEE ALSO -------- gitlink:git-annotate[1] From 4b3b1e1e488fe83a8a889ff26cf88355692b6a8c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 21 Jan 2007 11:04:13 -0800 Subject: [PATCH 41/47] git-push through git protocol This allows pushing over the git:// protocol, and while it's not authenticated, it could make sense from within a firewalled setup where nobody but trusted internal people can reach the git port. git-daemon is possibly easier and faster to set up in the kind of situation where you set up git instead of CVS inside a company. "git-receive-pack" is disabled by default, so you need to enable it explicitly by starting git-daemon with the "--enable=receive-pack" command line argument, or by having your config enable it automatically. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- daemon.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/daemon.c b/daemon.c index f039534d65..9590372214 100644 --- a/daemon.c +++ b/daemon.c @@ -372,9 +372,16 @@ static int upload_archive(void) return -1; } +static int receive_pack(void) +{ + execl_git_cmd("receive-pack", ".", NULL); + return -1; +} + static struct daemon_service daemon_service[] = { { "upload-archive", "uploadarch", upload_archive, 0, 1 }, { "upload-pack", "uploadpack", upload_pack, 1, 1 }, + { "receive-pack", "receivepack", receive_pack, 0, 1 }, }; static void enable_service(const char *name, int ena) { From cace16fdcb5d1a3518f92e04c65e78f06b0cd051 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 28 Jan 2007 12:53:26 -0800 Subject: [PATCH 42/47] Add a sample program 'blameview' to show how to use git-blame --incremental Signed-off-by: Junio C Hamano --- contrib/blameview/README | 10 +++ contrib/blameview/blameview.perl | 118 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 contrib/blameview/README create mode 100755 contrib/blameview/blameview.perl diff --git a/contrib/blameview/README b/contrib/blameview/README new file mode 100644 index 0000000000..50a6f67fd6 --- /dev/null +++ b/contrib/blameview/README @@ -0,0 +1,10 @@ +This is a sample program to use 'git-blame --incremental', based +on this message. + +From: Jeff King +Subject: Re: More precise tag following +To: Linus Torvalds +Cc: git@vger.kernel.org +Date: Sat, 27 Jan 2007 18:52:38 -0500 +Message-ID: <20070127235238.GA28706@coredump.intra.peff.net> + diff --git a/contrib/blameview/blameview.perl b/contrib/blameview/blameview.perl new file mode 100755 index 0000000000..a55f799f00 --- /dev/null +++ b/contrib/blameview/blameview.perl @@ -0,0 +1,118 @@ +#!/usr/bin/perl + +use Gtk2 -init; +use Gtk2::SimpleList; + +my $fn = shift or die "require filename to blame"; + +Gtk2::Rc->parse_string(<<'EOS'); +style "treeview_style" +{ + GtkTreeView::vertical-separator = 0 +} +class "GtkTreeView" style "treeview_style" +EOS + +my $window = Gtk2::Window->new('toplevel'); +$window->signal_connect(destroy => sub { Gtk2->main_quit }); +my $scrolled_window = Gtk2::ScrolledWindow->new; +$window->add($scrolled_window); +my $fileview = Gtk2::SimpleList->new( + 'Commit' => 'text', + 'CommitInfo' => 'text', + 'FileLine' => 'text', + 'Data' => 'text' +); +$scrolled_window->add($fileview); +$fileview->get_column(0)->set_spacing(0); +$fileview->set_size_request(1024, 768); +$fileview->set_rules_hint(1); + +open(my $fh, '<', $fn) + or die "unable to open $fn: $!"; +while(<$fh>) { + chomp; + $fileview->{data}->[$.] = ['HEAD', '?', "$fn:$.", $_]; +} + +my $blame; +open($blame, '-|', qw(git blame --incremental --), $fn) + or die "cannot start git-blame $fn"; + +Glib::IO->add_watch(fileno($blame), 'in', \&read_blame_line); + +$window->show_all; +Gtk2->main; +exit 0; + +my %commitinfo = (); + +sub flush_blame_line { + my ($attr) = @_; + + return unless defined $attr; + + my ($commit, $s_lno, $lno, $cnt) = + @{$attr}{qw(COMMIT S_LNO LNO CNT)}; + + my ($filename, $author, $author_time, $author_tz) = + @{$commitinfo{$commit}}{qw(FILENAME AUTHOR AUTHOR-TIME AUTHOR-TZ)}; + my $info = $author . ' ' . format_time($author_time, $author_tz); + + for(my $i = 0; $i < $cnt; $i++) { + @{$fileview->{data}->[$lno+$i-1]}[0,1,2] = + (substr($commit, 0, 8), $info, + $filename . ':' . ($s_lno+$i)); + } +} + +my $buf; +my $current; +sub read_blame_line { + + my $r = sysread($blame, $buf, 1024, length($buf)); + die "I/O error" unless defined $r; + + if ($r == 0) { + flush_blame_line($current); + $current = undef; + return 0; + } + + while ($buf =~ s/([^\n]*)\n//) { + my $line = $1; + + if (($commit, $s_lno, $lno, $cnt) = + ($line =~ /^([0-9a-f]{40}) (\d+) (\d+) (\d+)$/)) { + flush_blame_line($current); + $current = +{ + COMMIT => $1, + S_LNO => $2, + LNO => $3, + CNT => $4, + }; + next; + } + + # extended attribute values + if ($line =~ /^(author|author-mail|author-time|author-tz|committer|committer-mail|committer-time|committer-tz|summary|filename) (.*)$/) { + my $commit = $current->{COMMIT}; + $commitinfo{$commit}{uc($1)} = $2; + next; + } + } + return 1; +} + +sub format_time { + my $time = shift; + my $tz = shift; + + my $minutes = $tz < 0 ? 0-$tz : $tz; + $minutes = ($minutes / 100)*60 + ($minutes % 100); + $minutes = $tz < 0 ? 0-$minutes : $minutes; + $time += $minutes * 60; + my @t = gmtime($time); + return sprintf('%04d-%02d-%02d %02d:%02d:%02d %s', + $t[5] + 1900, @t[4,3,2,1,0], $tz); +} From 5558e55c06a1e897f3064f0c8a343d5c9858f6b2 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 28 Jan 2007 02:39:13 -0500 Subject: [PATCH 43/47] Teach for-each-ref about a little language called Tcl. Love it or hate it, some people actually still program in Tcl. Some of those programs are meant for interfacing with Git. Programs such as gitk and git-gui. It may be useful to have Tcl-safe output available from for-each-ref, just like shell, Perl and Python already enjoy. Thanks to Sergey Vlasov for pointing out the horrible flaws in the first and second version of this patch, and steering me in the right direction for Tcl value quoting. Signed-off-by: Shawn O. Pearce Signed-off-by: Junio C Hamano --- Documentation/git-for-each-ref.txt | 4 ++-- builtin-for-each-ref.c | 10 +++++++++ quote.c | 34 ++++++++++++++++++++++++++++++ quote.h | 1 + 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 06e7ab1ec1..da52eba7b3 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -7,7 +7,7 @@ git-for-each-ref - Output information on each ref SYNOPSIS -------- -'git-for-each-ref' [--count=]\* [--shell|--perl|--python] [--sort=]\* [--format=] [] +'git-for-each-ref' [--count=]\* [--shell|--perl|--python|--tcl] [--sort=]\* [--format=] [] DESCRIPTION ----------- @@ -49,7 +49,7 @@ OPTIONS using fnmatch(3). Refs that do not match the pattern are not shown. ---shell, --perl, --python:: +--shell, --perl, --python, --tcl:: If given, strings that substitute `%(fieldname)` placeholders are quoted as string literals suitable for the specified host language. This is meant to produce diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index af72a12a57..9d5f266dc4 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -12,6 +12,7 @@ #define QUOTE_SHELL 1 #define QUOTE_PERL 2 #define QUOTE_PYTHON 3 +#define QUOTE_TCL 4 typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; @@ -723,6 +724,9 @@ static void print_value(struct refinfo *ref, int atom, int quote_style) case QUOTE_PYTHON: python_quote_print(stdout, v->s); break; + case QUOTE_TCL: + tcl_quote_print(stdout, v->s); + break; } } @@ -834,6 +838,12 @@ int cmd_for_each_ref(int ac, const char **av, char *prefix) quote_style = QUOTE_PYTHON; continue; } + if (!strcmp(arg, "--tcl") ) { + if (0 <= quote_style) + die("more than one quoting style?"); + quote_style = QUOTE_TCL; + continue; + } if (!strncmp(arg, "--count=", 8)) { if (maxcount) die("more than one --count?"); diff --git a/quote.c b/quote.c index a418a0f803..fb9e4ca253 100644 --- a/quote.c +++ b/quote.c @@ -387,3 +387,37 @@ void python_quote_print(FILE *stream, const char *src) } fputc(sq, stream); } + +void tcl_quote_print(FILE *stream, const char *src) +{ + char c; + + fputc('"', stream); + while ((c = *src++)) { + switch (c) { + case '[': case ']': + case '{': case '}': + case '$': case '\\': case '"': + fputc('\\', stream); + default: + fputc(c, stream); + break; + case '\f': + fputs("\\f", stream); + break; + case '\r': + fputs("\\r", stream); + break; + case '\n': + fputs("\\n", stream); + break; + case '\t': + fputs("\\t", stream); + break; + case '\v': + fputs("\\v", stream); + break; + } + } + fputc('"', stream); +} diff --git a/quote.h b/quote.h index b55e699750..bdc3610df5 100644 --- a/quote.h +++ b/quote.h @@ -55,5 +55,6 @@ extern void write_name_quoted(const char *prefix, int prefix_len, /* quoting as a string literal for other languages */ extern void perl_quote_print(FILE *stream, const char *src); extern void python_quote_print(FILE *stream, const char *src); +extern void tcl_quote_print(FILE *stream, const char *src); #endif From a69aba6af3e96f8021c194691a851e78febd70bf Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Fri, 26 Jan 2007 08:58:48 +0000 Subject: [PATCH 44/47] UNIX reference time of 1970-01-01 00:00 is UTC timezone, not local time zone I got bitten because in the UK (where one would expect 1970-01-01 00:00 to be UTC 0) some politicians decided to mess around with daylight savings time from 1968 to 1971; it was permanently BST (+0100). That means that on my computer the following is true: $ date --date="1970-01-01 00:00" +"%F %T %z (%Z)" 1970-01-01 00:00:00 +0100 (BST) This of course means that the --date argument to date is specified in local time, not UTC. So when the hooks--update script does this: date=$(date --date="1970-01-01 00:00:00 $ts seconds") It's actually saying (in my timezone) "1970-01-01 01:00:00 UTC" + $ts. Clearly this is wrong. The UNIX epoch started at midnight UTC not 1am UTC. This leads to the tagged time in hooks--update being shown as one hour earlier than the true tagged time (in my timezone). The problem would be worse for other timezones. For a +1300 timezone on 1970-01-01, the tagged time would be 13 hours earlier. Oops. The solution is to force the reference time to UTC, which is what this patch does. In my timezone: $ date --date="1970-01-01 00:00 +0000" +"%F %T %z (%Z)" 1970-01-01 01:00:00 +0100 (BST) Much better. Signed-off-by: Andy Parkins --- templates/hooks--update | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/hooks--update b/templates/hooks--update index 9863a800c8..81f706fb0d 100644 --- a/templates/hooks--update +++ b/templates/hooks--update @@ -46,7 +46,7 @@ then if [ "$ref_type" = tag ]; then eval $(git cat-file tag $3 | \ sed -n '4s/tagger \([^>]*>\)[^0-9]*\([0-9]*\).*/tagger="\1" ts="\2"/p') - date=$(date --date="1970-01-01 00:00:00 $ts seconds" +"$date_format") + date=$(date --date="1970-01-01 00:00:00 +0000 $ts seconds" +"$date_format") echo "Tag '$tag' created by $tagger at $date" git cat-file tag $3 | sed -n '5,$p' echo From 829a686f1b50ba96cac2d88494fa339efe0c0862 Mon Sep 17 00:00:00 2001 From: Andy Parkins Date: Fri, 26 Jan 2007 09:01:04 +0000 Subject: [PATCH 45/47] Heavily expanded update hook to send more useful emails than the old hook I know it's only an example, but having this might save someone else the trouble of writing an enhanced version for themselves. It basically does the same job as the old update hook, but with these differences: * The recipients list is read from the repository config file from hooks.mailinglist * Updating unannotated tags can be allowed by setting hooks.allowunannotated * Announcement emails (via annotated tag creation) can be sent to a different mailing list by setting hooks.announcelist * Output email is more verbose and generates specific content depending on whether the ref is a tag, an annotated tag, a branch, or a tracking branch * The email is easier to filter; the subject line is prefixed with [SCM] and a project description pulled from the "description" file * It catches (and displays differently) branch updates that are performed with a --force Obviously, it's nothing that clever - it's the update hook I use on my repositories but I've tried to keep it general, and tried to make the output always relevant to the type of update. Signed-off-by: Andy Parkins Signed-off-by: Junio C Hamano --- templates/hooks--update | 336 +++++++++++++++++++++++++++++++--------- 1 file changed, 266 insertions(+), 70 deletions(-) diff --git a/templates/hooks--update b/templates/hooks--update index 81f706fb0d..4bd9d96ff9 100644 --- a/templates/hooks--update +++ b/templates/hooks--update @@ -1,89 +1,285 @@ #!/bin/sh # # An example hook script to mail out commit update information. -# It also blocks tags that aren't annotated. +# It can also blocks tags that aren't annotated. # Called by git-receive-pack with arguments: refname sha1-old sha1-new # -# To enable this hook: -# (1) change the recipient e-mail address -# (2) make this file executable by "chmod +x update". +# To enable this hook, make this file executable by "chmod +x update". # +# Config +# ------ +# hooks.mailinglist +# This is the list that all pushes will go to; leave it blank to not send +# emails frequently. The log email will list every log entry in full between +# the old ref value and the new ref value. +# hooks.announcelist +# This is the list that all pushes of annotated tags will go to. Leave it +# blank to just use the mailinglist field. The announce emails list the +# short log summary of the changes since the last annotated tag +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# +# Notes +# ----- +# All emails have their subjects prefixed with "[SCM]" to aid filtering. +# All emails include the headers "X-Git-Refname", "X-Git-Oldrev", +# "X-Git-Newrev", and "X-Git-Reftype" to enable fine tuned filtering and info. -project=$(cat $GIT_DIR/description) -recipients="commit-list@somewhere.com commit-list@somewhereelse.com" +# --- Constants +EMAILPREFIX="[SCM] " +LOGBEGIN="- Log -----------------------------------------------------------------" +LOGEND="-----------------------------------------------------------------------" +DATEFORMAT="%F %R %z" -ref_type=$(git cat-file -t "$3") +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" -# Only allow annotated tags in a shared repo -# Remove this code to treat dumb tags the same as everything else -case "$1","$ref_type" in -refs/tags/*,commit) - echo "*** Un-annotated tags are not allowed in this repo" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1;; -refs/tags/*,tag) - echo "### Pushing version '${1##refs/tags/}' to the masses" >&2 - # recipients="release-announce@somwehere.com announce@somewhereelse.com" - ;; -esac +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi -# set this to 'cat' to get a very detailed listing. -# short only kicks in when an annotated tag is added -short='git shortlog' +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "Usage: $0 " >&2 + exit 1 +fi -# see 'date --help' for info on how to write this -# The default is a human-readable iso8601-like format with minute -# precision ('2006-01-25 15:58 +0100' for example) -date_format="%F %R %z" +# --- Config +projectdesc=$(cat $GIT_DIR/description) +recipients=$(git-repo-config hooks.mailinglist) +announcerecipients=$(git-repo-config hooks.announcelist) +allowunannotated=$(git-repo-config --bool hooks.allowunannotated) -(if expr "$2" : '0*$' >/dev/null -then - # new ref - case "$1" in - refs/tags/*) - # a pushed and annotated tag (usually) means a new version - tag="${1##refs/tags/}" - if [ "$ref_type" = tag ]; then - eval $(git cat-file tag $3 | \ - sed -n '4s/tagger \([^>]*>\)[^0-9]*\([0-9]*\).*/tagger="\1" ts="\2"/p') - date=$(date --date="1970-01-01 00:00:00 +0000 $ts seconds" +"$date_format") - echo "Tag '$tag' created by $tagger at $date" - git cat-file tag $3 | sed -n '5,$p' - echo - fi - prev=$(git describe "$3^" | sed 's/-g.*//') - # the first tag in a repo will yield no $prev - if [ -z "$prev" ]; then - echo "Changes since the dawn of time:" - git rev-list --pretty $3 | $short - else - echo "Changes since $prev:" - git rev-list --pretty $prev..$3 | $short - echo --- - git diff --stat $prev..$3 - echo --- +# --- Check types +newrev_type=$(git-cat-file -t "$newrev") + +case "$refname","$newrev_type" in + refs/tags/*,commit) + # un-annoted tag + refname_type="tag" + short_refname=${refname##refs/tags/} + if [ $allowunannotated != "true" ]; then + echo "*** The un-annotated tag, $short_refname is not allowed in this repository" >&2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 fi ;; - - refs/heads/*) - branch="${1##refs/heads/}" - echo "New branch '$branch' available with the following commits:" - git-rev-list --pretty "$3" $(git-rev-parse --not --all) + refs/tags/*,tag) + # annotated tag + refname_type="annotated tag" + short_refname=${refname##refs/tags/} + # change recipients + if [ -n "$announcerecipients" ]; then + recipients="$announcerecipients" + fi ;; - esac -else - base=$(git-merge-base "$2" "$3") - case "$base" in - "$2") - git diff --stat "$3" "^$base" - echo - echo "New commits:" + refs/heads/*,commit) + # branch + refname_type="branch" + short_refname=${refname##refs/heads/} + ;; + refs/remotes/*,commit) + # tracking branch + refname_type="tracking branch" + short_refname=${refname##refs/remotes/} + # Should this even be allowed? + echo "*** Push-update of tracking branch, $refname. No email generated." >&2 + exit 0 ;; *) - echo "Rebased ref, commits from common ancestor:" + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update, \"$newrev_type\", to ref $refname" >&2 + exit 1 ;; - esac - git-rev-list --pretty "$3" "^$base" -fi) | -mail -s "$project: Changes to '${1##refs/heads/}'" $recipients +esac + +# Check if we've got anyone to send to +if [ -z "$recipients" ]; then + # If the email isn't sent, then at least give the user some idea of what command + # would generate the email at a later date + echo "*** No recipients found - no email will be sent, but the push will continue" >&2 + echo "*** for $0 $1 $2 $3" >&2 + exit 0 +fi + +# --- Email parameters +committer=$(git show --pretty=full -s $newrev | grep "^Commit: " | sed -e "s/^Commit: //") +describe=$(git describe $newrev 2>/dev/null) +if [ -z "$describe" ]; then + describe=$newrev +fi + +# --- Email (all stdout will be the email) +( +# Generate header +cat <<-EOF +From: $committer +To: $recipients +Subject: ${EMAILPREFIX}$projectdesc $refname_type, $short_refname now at $describe +X-Git-Refname: $refname +X-Git-Reftype: $refname_type +X-Git-Oldrev: $oldrev +X-Git-Newrev: $newrev + +Hello, + +This is an automated email from the git hooks/update script, it was +generated because a ref change was pushed to the repository. + +Updating $refname_type, $short_refname, +EOF + +case "$refname_type" in + "tracking branch"|branch) + if expr "$oldrev" : '0*$' >/dev/null + then + # If the old reference is "0000..0000" then this is a new branch + # and so oldrev is not valid + echo " as a new $refname_type" + echo " to $newrev ($newrev_type)" + echo "" + echo $LOGBEGIN + # This shows all log entries that are not already covered by + # another ref - i.e. commits that are now accessible from this + # ref that were previously not accessible + git-rev-list --pretty $newref $(git-rev-parse --not --all) + echo $LOGEND + else + # oldrev is valid + oldrev_type=$(git-cat-file -t "$oldrev") + + # Now the problem is for cases like this: + # * --- * --- * --- * (oldrev) + # \ + # * --- * --- * (newrev) + # i.e. there is no guarantee that newrev is a strict subset + # of oldrev - (would have required a force, but that's allowed). + # So, we can't simply say rev-list $oldrev..$newrev. Instead + # we find the common base of the two revs and list from there + baserev=$(git-merge-base $oldrev $newrev) + + # Commit with a parent + for rev in $(git-rev-list $newrev ^$baserev) + do + revtype=$(git-cat-file -t "$rev") + echo " via $rev ($revtype)" + done + if [ "$baserev" = "$oldrev" ]; then + echo " from $oldrev ($oldrev_type)" + else + echo " based on $baserev" + echo " from $oldrev ($oldrev_type)" + echo "" + echo "This ref update crossed a branch point; i.e. the old rev is not a strict subset" + echo "of the new rev. This occurs, when you --force push a change in a situation" + echo "like this:" + echo "" + echo " * -- * -- B -- O -- O -- O ($oldrev)" + echo " \\" + echo " N -- N -- N ($newrev)" + echo "" + echo "Therefore, we assume that you've already had alert emails for all of the O" + echo "revisions, and now give you all the revisions in the N branch from the common" + echo "base, B ($baserev), up to the new revision." + fi + echo "" + echo $LOGBEGIN + git-rev-list --pretty $newrev ^$baserev + echo $LOGEND + echo "" + echo "Diffstat:" + git-diff-tree --no-color --stat -M -C --find-copies-harder $newrev ^$baserev + fi + ;; + "annotated tag") + # Should we allow changes to annotated tags? + if expr "$oldrev" : '0*$' >/dev/null + then + # If the old reference is "0000..0000" then this is a new atag + # and so oldrev is not valid + echo " to $newrev ($newrev_type)" + else + echo " to $newrev ($newrev_type)" + echo " from $oldrev" + fi + + # If this tag succeeds another, then show which tag it replaces + prevtag=$(git describe $newrev^ 2>/dev/null | sed 's/-g.*//') + if [ -n "$prevtag" ]; then + echo " replaces $prevtag" + fi + + # Read the tag details + eval $(git cat-file tag $newrev | \ + sed -n '4s/tagger \([^>]*>\)[^0-9]*\([0-9]*\).*/tagger="\1" ts="\2"/p') + tagged=$(date --date="1970-01-01 00:00:00 +0000 $ts seconds" +"$DATEFORMAT") + + echo " tagged by $tagger" + echo " on $tagged" + + echo "" + echo $LOGBEGIN + echo "" + + if [ -n "$prevtag" ]; then + git rev-list --pretty=short "$prevtag..$newrev" | git shortlog + else + git rev-list --pretty=short $newrev | git shortlog + fi + + echo $LOGEND + echo "" + ;; + *) + # By default, unannotated tags aren't allowed in; if + # they are though, it's debatable whether we would even want an + # email to be generated; however, I don't want to add another config + # option just for that. + # + # Unannotated tags are more about marking a point than releasing + # a version; therefore we don't do the shortlog summary that we + # do for annotated tags above - we simply show that the point has + # been marked, and print the log message for the marked point for + # reference purposes + # + # Note this section also catches any other reference type (although + # there aren't any) and deals with them in the same way. + if expr "$oldrev" : '0*$' >/dev/null + then + # If the old reference is "0000..0000" then this is a new tag + # and so oldrev is not valid + echo " as a new $refname_type" + echo " to $newrev ($newrev_type)" + else + echo " to $newrev ($newrev_type)" + echo " from $oldrev" + fi + echo "" + echo $LOGBEGIN + git-show --no-color --root -s $newrev + echo $LOGEND + echo "" + ;; +esac + +# Footer +cat <<-EOF + +hooks/update +--- +Git Source Code Management System +$0 $1 \\ + $2 \\ + $3 +EOF +#) | cat >&2 +) | /usr/sbin/sendmail -t + +# --- Finished exit 0 From e0d10e1c63bc52b37bbec99b07deee794058d9b4 Mon Sep 17 00:00:00 2001 From: Tom Prince Date: Sun, 28 Jan 2007 16:16:53 -0800 Subject: [PATCH 46/47] [PATCH] Rename git-repo-config to git-config. Signed-off-by: Tom Prince Signed-off-by: Junio C Hamano --- .gitignore | 1 + Documentation/cmd-list.perl | 2 +- Documentation/config.txt | 2 +- Documentation/core-tutorial.txt | 2 +- Documentation/cvs-migration.txt | 2 +- Documentation/everyday.txt | 4 +- Documentation/git-config.txt | 227 ++++++++++++++++++ Documentation/git-pull.txt | 4 +- Documentation/git-remote.txt | 4 +- Documentation/git-repo-config.txt | 217 +---------------- Documentation/git-svn.txt | 20 +- Documentation/git-update-index.txt | 4 +- Documentation/git-var.txt | 4 +- Documentation/git.txt | 2 +- .../howto/setup-git-server-over-http.txt | 4 +- Documentation/tutorial.txt | 8 +- Makefile | 4 +- builtin-repo-config.c => builtin-config.c | 4 +- builtin.h | 2 +- contrib/completion/git-completion.bash | 15 +- contrib/emacs/git.el | 8 +- contrib/gitview/gitview | 2 +- contrib/remotes2config.sh | 4 +- git-clone.sh | 10 +- git-commit.sh | 4 +- git-cvsserver.perl | 6 +- git-fetch.sh | 2 +- git-instaweb.sh | 10 +- git-ls-remote.sh | 2 +- git-merge.sh | 4 +- git-p4import.py | 4 +- git-parse-remote.sh | 14 +- git-remote.perl | 8 +- git-repack.sh | 2 +- git-revert.sh | 2 +- git-sh-setup.sh | 2 +- git-svn.perl | 20 +- git.c | 3 +- gitk | 2 +- gitweb/gitweb.perl | 2 +- ident.c | 4 +- perl/Git.pm | 8 +- t/t1300-repo-config.sh | 102 ++++---- t/t1400-update-ref.sh | 4 +- t/t1410-reflog.sh | 2 +- t/t3200-branch.sh | 6 +- t/t3700-add.sh | 6 +- t/t3900-i18n-commit.sh | 24 +- t/t3901-i18n-patch.sh | 58 ++--- t/t4000-diff-format.sh | 2 +- t/t4006-diff-mode.sh | 2 +- t/t4013-diff-various.sh | 2 +- t/t4102-apply-rename.sh | 2 +- t/t5301-sliding-window.sh | 14 +- t/t5400-send-pack.sh | 2 +- t/t5500-fetch-pack.sh | 2 +- t/t5510-fetch.sh | 10 +- t/t6200-fmt-merge-msg.sh | 6 +- 58 files changed, 460 insertions(+), 439 deletions(-) create mode 100644 Documentation/git-config.txt rename builtin-repo-config.c => builtin-config.c (94%) diff --git a/.gitignore b/.gitignore index 6da1cdbd0d..b4dccd7b81 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ git-clean git-clone git-commit git-commit-tree +git-config git-convert-objects git-count-objects git-cvsexportcommit diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 744db82413..824462551f 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -144,7 +144,7 @@ git-receive-pack synchelpers git-reflog ancillarymanipulators git-relink ancillarymanipulators git-repack ancillarymanipulators -git-repo-config ancillarymanipulators +git-config ancillarymanipulators git-request-pull foreignscminterface git-rerere ancillaryinterrogators git-reset mainporcelain diff --git a/Documentation/config.txt b/Documentation/config.txt index ebda2e0f61..e5e019fedd 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -62,7 +62,7 @@ The values following the equals sign in variable assign are all either a string, an integer, or a boolean. Boolean values may be given as yes/no, 0/1 or true/false. Case is not significant in boolean values, when converting value to the canonical form using '--bool' type specifier; -`git-repo-config` will ensure that the output is "true" or "false". +`git-config` will ensure that the output is "true" or "false". String values may be entirely or partially enclosed in double quotes. You need to enclose variable value in double quotes if you want to diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt index 7317489cfc..86a9c7521a 100644 --- a/Documentation/core-tutorial.txt +++ b/Documentation/core-tutorial.txt @@ -1130,7 +1130,7 @@ the remote repository URL in the local repository's config file like this: ------------------------------------------------ -$ git repo-config remote.linus.url http://www.kernel.org/pub/scm/git/git.git/ +$ 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. diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt index 775bf4266a..764cc560b4 100644 --- a/Documentation/cvs-migration.txt +++ b/Documentation/cvs-migration.txt @@ -36,7 +36,7 @@ them first before running git pull. ================================ The `pull` command knows where to get updates from because of certain configuration variables that were set by the first `git clone` -command; see `git repo-config -l` and the gitlink:git-repo-config[1] man +command; see `git config -l` and the gitlink:git-config[1] man page for details. ================================ diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt index ca36a76da6..fbbbc92b81 100644 --- a/Documentation/everyday.txt +++ b/Documentation/everyday.txt @@ -212,12 +212,12 @@ Push into another repository.:: ------------ satellite$ git clone mothership:frotz frotz <1> satellite$ cd frotz -satellite$ git repo-config --get-regexp '^(remote|branch)\.' <2> +satellite$ git config --get-regexp '^(remote|branch)\.' <2> remote.origin.url mothership:frotz remote.origin.fetch refs/heads/*:refs/remotes/origin/* branch.master.remote origin branch.master.merge refs/heads/master -satellite$ git repo-config remote.origin.push \ +satellite$ git config remote.origin.push \ master:refs/remotes/satellite/master <3> satellite$ edit/compile/test/commit satellite$ git push origin <4> diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt new file mode 100644 index 0000000000..6624484fe1 --- /dev/null +++ b/Documentation/git-config.txt @@ -0,0 +1,227 @@ +git-config(1) +============= + +NAME +---- +git-config - Get and set repository or global options + + +SYNOPSIS +-------- +[verse] +'git-config' [--global] [type] name [value [value_regex]] +'git-config' [--global] [type] --add name value +'git-config' [--global] [type] --replace-all name [value [value_regex]] +'git-config' [--global] [type] --get name [value_regex] +'git-config' [--global] [type] --get-all name [value_regex] +'git-config' [--global] [type] --unset name [value_regex] +'git-config' [--global] [type] --unset-all name [value_regex] +'git-config' [--global] -l | --list + +DESCRIPTION +----------- +You can query/set/replace/unset options with this command. The name is +actually the section and the key separated by a dot, and the value will be +escaped. + +Multiple lines can be added to an option by using the '--add' option. +If you want to update or unset an option which can occur on multiple +lines, a POSIX regexp `value_regex` needs to be given. Only the +existing values that match the regexp are updated or unset. If +you want to handle the lines that do *not* match the regex, just +prepend a single exclamation mark in front (see EXAMPLES). + +The type specifier can be either '--int' or '--bool', which will make +'git-config' ensure that the variable(s) are of the given type and +convert the value to the canonical form (simple decimal number for int, +a "true" or "false" string for bool). If no type specifier is passed, +no checks or transformations are performed on the value. + +This command will fail if: + +. The .git/config file is invalid, +. Can not write to .git/config, +. no section was provided, +. the section or key is invalid, +. you try to unset an option which does not exist, +. you try to unset/set an option for which multiple lines match, or +. you use --global option without $HOME being properly set. + + +OPTIONS +------- + +--replace-all:: + Default behavior is to replace at most one line. This replaces + all lines matching the key (and optionally the value_regex). + +--add:: + Adds a new line to the option without altering any existing + values. This is the same as providing '^$' as the value_regex. + +--get:: + Get the value for a given key (optionally filtered by a regex + matching the value). Returns error code 1 if the key was not + found and error code 2 if multiple key values were found. + +--get-all:: + Like get, but does not fail if the number of values for the key + is not exactly one. + +--get-regexp:: + Like --get-all, but interprets the name as a regular expression. + +--global:: + Use global ~/.gitconfig file rather than the repository .git/config. + +--unset:: + Remove the line matching the key from config file. + +--unset-all:: + Remove all matching lines from config file. + +-l, --list:: + List all variables set in config file. + +--bool:: + git-config will ensure that the output is "true" or "false" + +--int:: + git-config will ensure that the output is a simple + decimal number. An optional value suffix of 'k', 'm', or 'g' + in the config file will cause the value to be multiplied + by 1024, 1048576, or 1073741824 prior to output. + + +ENVIRONMENT +----------- + +GIT_CONFIG:: + Take the configuration from the given file instead of .git/config. + Using the "--global" option forces this to ~/.gitconfig. + +GIT_CONFIG_LOCAL:: + Currently the same as $GIT_CONFIG; when Git will support global + configuration files, this will cause it to take the configuration + from the global configuration file in addition to the given file. + + +EXAMPLE +------- + +Given a .git/config like this: + + # + # This is the config file, and + # a '#' or ';' character indicates + # a comment + # + + ; core variables + [core] + ; Don't trust file modes + filemode = false + + ; Our diff algorithm + [diff] + external = "/usr/local/bin/gnu-diff -u" + renames = true + + ; Proxy settings + [core] + gitproxy="ssh" for "ssh://kernel.org/" + gitproxy="proxy-command" for kernel.org + gitproxy="myprotocol-command" for "my://" + gitproxy=default-proxy ; for all the rest + +you can set the filemode to true with + +------------ +% git config core.filemode true +------------ + +The hypothetical proxy command entries actually have a postfix to discern +what URL they apply to. Here is how to change the entry for kernel.org +to "ssh". + +------------ +% git config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$' +------------ + +This makes sure that only the key/value pair for kernel.org is replaced. + +To delete the entry for renames, do + +------------ +% git config --unset diff.renames +------------ + +If you want to delete an entry for a multivar (like core.gitproxy above), +you have to provide a regex matching the value of exactly one line. + +To query the value for a given key, do + +------------ +% git config --get core.filemode +------------ + +or + +------------ +% git config core.filemode +------------ + +or, to query a multivar: + +------------ +% git config --get core.gitproxy "for kernel.org$" +------------ + +If you want to know all the values for a multivar, do: + +------------ +% git config --get-all core.gitproxy +------------ + +If you like to live dangerous, you can replace *all* core.gitproxy by a +new one with + +------------ +% git config --replace-all core.gitproxy ssh +------------ + +However, if you really only want to replace the line for the default proxy, +i.e. the one without a "for ..." postfix, do something like this: + +------------ +% git config core.gitproxy ssh '! for ' +------------ + +To actually match only values with an exclamation mark, you have to + +------------ +% git config section.key value '[!]' +------------ + +To add a new proxy, without altering any of the existing ones, use + +------------ +% git config core.gitproxy '"proxy" for example.com' +------------ + + +include::config.txt[] + + +Author +------ +Written by Johannes Schindelin + +Documentation +-------------- +Documentation by Johannes Schindelin, Petr Baudis and the git-list . + +GIT +--- +Part of the gitlink:git[7] suite + diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 3e5f115728..a81d68ccef 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -42,7 +42,7 @@ git pull, git pull origin:: current branch. Normally the branch merged in is the HEAD of the remote repository, but the choice is determined by the branch..remote and - branch..merge options; see gitlink:git-repo-config[1] + branch..merge options; see gitlink:git-config[1] for details. git pull origin next:: @@ -94,7 +94,7 @@ gitlink:git-reset[1]. SEE ALSO -------- -gitlink:git-fetch[1], gitlink:git-merge[1], gitlink:git-repo-config[1] +gitlink:git-fetch[1], gitlink:git-merge[1], gitlink:git-config[1] Author diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 5b93a8c8be..358c1acfc3 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -28,7 +28,7 @@ In the third form, gives some information about the remote . The remote configuration is achieved using the `remote.origin.url` and `remote.origin.fetch` configuration variables. (See -gitlink:git-repo-config[1]). +gitlink:git-config[1]). Examples -------- @@ -58,7 +58,7 @@ See Also -------- gitlink:git-fetch[1] gitlink:git-branch[1] -gitlink:git-repo-config[1] +gitlink:git-config[1] Author ------ diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt index 9db3d30825..2deba31763 100644 --- a/Documentation/git-repo-config.txt +++ b/Documentation/git-repo-config.txt @@ -8,220 +8,11 @@ git-repo-config - Get and set repository or global options SYNOPSIS -------- -[verse] -'git-repo-config' [--global] [type] name [value [value_regex]] -'git-repo-config' [--global] [type] --add name value -'git-repo-config' [--global] [type] --replace-all name [value [value_regex]] -'git-repo-config' [--global] [type] --get name [value_regex] -'git-repo-config' [--global] [type] --get-all name [value_regex] -'git-repo-config' [--global] [type] --unset name [value_regex] -'git-repo-config' [--global] [type] --unset-all name [value_regex] -'git-repo-config' [--global] -l | --list +'git-repo-config' ... + DESCRIPTION ----------- -You can query/set/replace/unset options with this command. The name is -actually the section and the key separated by a dot, and the value will be -escaped. - -Multiple lines can be added to an option by using the '--add' option. -If you want to update or unset an option which can occur on multiple -lines, a POSIX regexp `value_regex` needs to be given. Only the -existing values that match the regexp are updated or unset. If -you want to handle the lines that do *not* match the regex, just -prepend a single exclamation mark in front (see EXAMPLES). - -The type specifier can be either '--int' or '--bool', which will make -'git-repo-config' ensure that the variable(s) are of the given type and -convert the value to the canonical form (simple decimal number for int, -a "true" or "false" string for bool). If no type specifier is passed, -no checks or transformations are performed on the value. - -This command will fail if: - -. The .git/config file is invalid, -. Can not write to .git/config, -. no section was provided, -. the section or key is invalid, -. you try to unset an option which does not exist, -. you try to unset/set an option for which multiple lines match, or -. you use --global option without $HOME being properly set. - - -OPTIONS -------- - ---replace-all:: - Default behavior is to replace at most one line. This replaces - all lines matching the key (and optionally the value_regex). - ---add:: - Adds a new line to the option without altering any existing - values. This is the same as providing '^$' as the value_regex. - ---get:: - Get the value for a given key (optionally filtered by a regex - matching the value). Returns error code 1 if the key was not - found and error code 2 if multiple key values were found. - ---get-all:: - Like get, but does not fail if the number of values for the key - is not exactly one. - ---get-regexp:: - Like --get-all, but interprets the name as a regular expression. - ---global:: - Use global ~/.gitconfig file rather than the repository .git/config. - ---unset:: - Remove the line matching the key from config file. - ---unset-all:: - Remove all matching lines from config file. - --l, --list:: - List all variables set in config file. - ---bool:: - git-repo-config will ensure that the output is "true" or "false" - ---int:: - git-repo-config will ensure that the output is a simple - decimal number. An optional value suffix of 'k', 'm', or 'g' - in the config file will cause the value to be multiplied - by 1024, 1048576, or 1073741824 prior to output. - - -ENVIRONMENT ------------ - -GIT_CONFIG:: - Take the configuration from the given file instead of .git/config. - Using the "--global" option forces this to ~/.gitconfig. - -GIT_CONFIG_LOCAL:: - Currently the same as $GIT_CONFIG; when Git will support global - configuration files, this will cause it to take the configuration - from the global configuration file in addition to the given file. - - -EXAMPLE -------- - -Given a .git/config like this: - - # - # This is the config file, and - # a '#' or ';' character indicates - # a comment - # - - ; core variables - [core] - ; Don't trust file modes - filemode = false - - ; Our diff algorithm - [diff] - external = "/usr/local/bin/gnu-diff -u" - renames = true - - ; Proxy settings - [core] - gitproxy="ssh" for "ssh://kernel.org/" - gitproxy="proxy-command" for kernel.org - gitproxy="myprotocol-command" for "my://" - gitproxy=default-proxy ; for all the rest - -you can set the filemode to true with - ------------- -% git repo-config core.filemode true ------------- - -The hypothetical proxy command entries actually have a postfix to discern -what URL they apply to. Here is how to change the entry for kernel.org -to "ssh". - ------------- -% git repo-config core.gitproxy '"ssh" for kernel.org' 'for kernel.org$' ------------- - -This makes sure that only the key/value pair for kernel.org is replaced. - -To delete the entry for renames, do - ------------- -% git repo-config --unset diff.renames ------------- - -If you want to delete an entry for a multivar (like core.gitproxy above), -you have to provide a regex matching the value of exactly one line. - -To query the value for a given key, do - ------------- -% git repo-config --get core.filemode ------------- - -or - ------------- -% git repo-config core.filemode ------------- - -or, to query a multivar: - ------------- -% git repo-config --get core.gitproxy "for kernel.org$" ------------- - -If you want to know all the values for a multivar, do: - ------------- -% git repo-config --get-all core.gitproxy ------------- - -If you like to live dangerous, you can replace *all* core.gitproxy by a -new one with - ------------- -% git repo-config --replace-all core.gitproxy ssh ------------- - -However, if you really only want to replace the line for the default proxy, -i.e. the one without a "for ..." postfix, do something like this: - ------------- -% git repo-config core.gitproxy ssh '! for ' ------------- - -To actually match only values with an exclamation mark, you have to - ------------- -% git repo-config section.key value '[!]' ------------- - -To add a new proxy, without altering any of the existing ones, use - ------------- -% git repo-config core.gitproxy '"proxy" for example.com' ------------- - - -include::config.txt[] - - -Author ------- -Written by Johannes Schindelin - -Documentation --------------- -Documentation by Johannes Schindelin, Petr Baudis and the git-list . - -GIT ---- -Part of the gitlink:git[7] suite +This is a synonym for gitlink:git-config[1]. Please refer to the +documentation of that command. diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index b95ff1da96..aea4a6bf5f 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -204,7 +204,7 @@ removed by default if there are no files left in them. git cannot version empty directories. Enabling this flag will make the commit to SVN act like git. -repo-config key: svn.rmdir +config key: svn.rmdir -e:: --edit:: @@ -215,7 +215,7 @@ Edit the commit message before committing to SVN. This is off by default for objects that are commits, and forced on when committing tree objects. -repo-config key: svn.edit +config key: svn.edit -l:: --find-copies-harder:: @@ -226,8 +226,8 @@ They are both passed directly to git-diff-tree see gitlink:git-diff-tree[1] for more information. [verse] -repo-config key: svn.l -repo-config key: svn.findcopiesharder +config key: svn.l +config key: svn.findcopiesharder -A:: --authors-file=:: @@ -245,7 +245,7 @@ will abort operation. The user will then have to add the appropriate entry. Re-running the previous git-svn command after the authors-file is modified should continue operation. -repo-config key: svn.authorsfile +config key: svn.authorsfile -q:: --quiet:: @@ -262,8 +262,8 @@ repo-config key: svn.authorsfile --repack-flags are passed directly to gitlink:git-repack[1]. -repo-config key: svn.repack -repo-config key: svn.repackflags +config key: svn.repack +config key: svn.repackflags -m:: --merge:: @@ -304,7 +304,7 @@ used to track branches across multiple SVN _repositories_. This option may be specified multiple times, once for each branch. -repo-config key: svn.branch +config key: svn.branch -i:: --id :: @@ -320,7 +320,7 @@ for more information on using GIT_SVN_ID. started tracking a branch and never tracked the trunk it was descended from. -repo-config key: svn.followparent +config key: svn.followparent --no-metadata:: This gets rid of the git-svn-id: lines at the end of every commit. @@ -332,7 +332,7 @@ repo-config key: svn.followparent The 'git-svn log' command will not work on repositories using this, either. -repo-config key: svn.nometadata +config key: svn.nometadata -- diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 5bbae42d86..b161c8b32b 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -289,7 +289,7 @@ Configuration The command honors `core.filemode` configuration variable. If your repository is on an filesystem whose executable bits are -unreliable, this should be set to 'false' (see gitlink:git-repo-config[1]). +unreliable, this should be set to 'false' (see gitlink:git-config[1]). This causes the command to ignore differences in file modes recorded in the index and the file mode on the filesystem if they differ only on executable bit. On such an unfortunate filesystem, you may @@ -301,7 +301,7 @@ The command looks at `core.ignorestat` configuration variable. See See Also -------- -gitlink:git-repo-config[1] +gitlink:git-config[1] Author diff --git a/Documentation/git-var.txt b/Documentation/git-var.txt index 8a50638e98..9b0de1c111 100644 --- a/Documentation/git-var.txt +++ b/Documentation/git-var.txt @@ -20,7 +20,7 @@ OPTIONS Cause the logical variables to be listed. In addition, all the variables of the git configuration file .git/config are listed as well. (However, the configuration variables listing functionality - is deprecated in favor of `git-repo-config -l`.) + is deprecated in favor of `git-config -l`.) EXAMPLE -------- @@ -49,7 +49,7 @@ See Also -------- gitlink:git-commit-tree[1] gitlink:git-tag[1] -gitlink:git-repo-config[1] +gitlink:git-config[1] Author ------ diff --git a/Documentation/git.txt b/Documentation/git.txt index 9761de36b3..7cd3467986 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -24,7 +24,7 @@ link:everyday.html[Everyday Git] for a useful minimum set of commands, and also want to read link:cvs-migration.html[CVS migration]. The COMMAND is either a name of a Git command (see below) or an alias -as defined in the configuration file (see gitlink:git-repo-config[1]). +as defined in the configuration file (see gitlink:git-config[1]). OPTIONS ------- diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.txt index a202f3a460..8eadc20494 100644 --- a/Documentation/howto/setup-git-server-over-http.txt +++ b/Documentation/howto/setup-git-server-over-http.txt @@ -205,7 +205,7 @@ To check whether all is OK, do: Now, add the remote in your existing repository which contains the project you want to export: - $ git-repo-config remote.upload.url \ + $ git-config remote.upload.url \ http://@/my-new-repo.git/ It is important to put the last '/'; Without it, the server will send @@ -222,7 +222,7 @@ From your client repository, do This pushes branch 'master' (which is assumed to be the branch you want to export) to repository called 'upload', which we previously -defined with git-repo-config. +defined with git-config. Troubleshooting: diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt index c27a4505d4..adb1e32750 100644 --- a/Documentation/tutorial.txt +++ b/Documentation/tutorial.txt @@ -16,8 +16,8 @@ public email address before doing any operation. The easiest way to do so is: ------------------------------------------------ -$ git repo-config --global user.name "Your Name Comes Here" -$ git repo-config --global user.email you@yourdomain.example.com +$ git config --global user.name "Your Name Comes Here" +$ git config --global user.email you@yourdomain.example.com ------------------------------------------------ @@ -353,12 +353,12 @@ repository in the repository configuration, and that location is used for pulls: ------------------------------------- -$ git repo-config --get remote.origin.url +$ git config --get remote.origin.url /home/bob/myrepo ------------------------------------- (The complete configuration created by git-clone is visible using -"git repo-config -l", and the gitlink:git-repo-config[1] man page +"git config -l", and the gitlink:git-config[1] man page explains the meaning of each option.) Git also keeps a pristine copy of Alice's master branch under the diff --git a/Makefile b/Makefile index 07246f3d18..fd8a522efa 100644 --- a/Makefile +++ b/Makefile @@ -213,7 +213,7 @@ EXTRA_PROGRAMS = BUILT_INS = \ git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \ - git-get-tar-commit-id$X git-init$X \ + git-get-tar-commit-id$X git-init$X git-repo-config$X \ $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) # what 'all' will build and 'install' will install, in gitexecdir @@ -299,7 +299,7 @@ BUILTIN_OBJS = \ builtin-push.o \ builtin-read-tree.o \ builtin-reflog.o \ - builtin-repo-config.o \ + builtin-config.o \ builtin-rerere.o \ builtin-rev-list.o \ builtin-rev-parse.o \ diff --git a/builtin-repo-config.c b/builtin-config.c similarity index 94% rename from builtin-repo-config.c rename to builtin-config.c index 90633119d4..0f9051da17 100644 --- a/builtin-repo-config.c +++ b/builtin-config.c @@ -2,7 +2,7 @@ #include "cache.h" static const char git_config_set_usage[] = -"git-repo-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list"; +"git-config [ --global ] [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --list"; static char *key; static regex_t *key_regexp; @@ -126,7 +126,7 @@ free_strings: return ret; } -int cmd_repo_config(int argc, const char **argv, const char *prefix) +int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = 0; setup_git_directory_gently(&nongit); diff --git a/builtin.h b/builtin.h index 0b3c9f62ef..cfe5990740 100644 --- a/builtin.h +++ b/builtin.h @@ -53,7 +53,7 @@ extern int cmd_prune_packed(int argc, const char **argv, const char *prefix); extern int cmd_push(int argc, const char **argv, const char *prefix); extern int cmd_read_tree(int argc, const char **argv, const char *prefix); extern int cmd_reflog(int argc, const char **argv, const char *prefix); -extern int cmd_repo_config(int argc, const char **argv, const char *prefix); +extern int cmd_config(int argc, const char **argv, const char *prefix); extern int cmd_rerere(int argc, const char **argv, const char *prefix); extern int cmd_rev_list(int argc, const char **argv, const char *prefix); extern int cmd_rev_parse(int argc, const char **argv, const char *prefix); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 7c7520ea29..83c69ecf48 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -145,7 +145,7 @@ __git_remotes () echo ${i#$d/remotes/} done [ "$ngoff" ] && shopt -u nullglob - for i in $(git --git-dir="$d" repo-config --list); do + for i in $(git --git-dir="$d" config --list); do case "$i" in remote.*.url=*) i="${i#remote.}" @@ -286,7 +286,7 @@ __git_commandlist="$(__git_commands 2>/dev/null)" __git_aliases () { local i IFS=$'\n' - for i in $(git --git-dir="$(__gitdir)" repo-config --list); do + for i in $(git --git-dir="$(__gitdir)" config --list); do case "$i" in alias.*) i="${i#alias.}" @@ -299,7 +299,7 @@ __git_aliases () __git_aliased_command () { local word cmdline=$(git --git-dir="$(__gitdir)" \ - repo-config --get "alias.$1") + config --get "alias.$1") for word in $cmdline; do if [ "${word##-*}" ]; then echo $word @@ -629,7 +629,7 @@ _git_rebase () COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur")) } -_git_repo_config () +_git_config () { local cur="${COMP_WORDS[COMP_CWORD]}" local prv="${COMP_WORDS[COMP_CWORD-1]}" @@ -806,6 +806,7 @@ _git () checkout) _git_checkout ;; cherry-pick) _git_cherry_pick ;; commit) _git_commit ;; + config) _git_config ;; diff) _git_diff ;; diff-tree) _git_diff_tree ;; fetch) _git_fetch ;; @@ -819,7 +820,7 @@ _git () pull) _git_pull ;; push) _git_push ;; rebase) _git_rebase ;; - repo-config) _git_repo_config ;; + repo-config) _git_config ;; reset) _git_reset ;; show) _git_show ;; show-branch) _git_log ;; @@ -856,7 +857,7 @@ complete -o default -F _git_name_rev git-name-rev complete -o default -o nospace -F _git_pull git-pull complete -o default -o nospace -F _git_push git-push complete -o default -F _git_rebase git-rebase -complete -o default -F _git_repo_config git-repo-config +complete -o default -F _git_config git-config complete -o default -F _git_reset git-reset complete -o default -o nospace -F _git_show git-show complete -o default -o nospace -F _git_log git-show-branch @@ -879,7 +880,7 @@ complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe complete -o default -F _git_merge_base git-merge-base.exe complete -o default -F _git_name_rev git-name-rev.exe complete -o default -o nospace -F _git_push git-push.exe -complete -o default -F _git_repo_config git-repo-config +complete -o default -F _git_config git-config complete -o default -o nospace -F _git_show git-show.exe complete -o default -o nospace -F _git_log git-show-branch.exe complete -o default -o nospace -F _git_log git-whatchanged.exe diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index d90ba816e0..24629eb3e2 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -222,7 +222,7 @@ and returns the process output as a string." "Return the name to use as GIT_COMMITTER_NAME." ; copied from log-edit (or git-committer-name - (git-repo-config "user.name") + (git-config "user.name") (and (boundp 'add-log-full-name) add-log-full-name) (and (fboundp 'user-full-name) (user-full-name)) (and (boundp 'user-full-name) user-full-name))) @@ -231,7 +231,7 @@ and returns the process output as a string." "Return the email address to use as GIT_COMMITTER_EMAIL." ; copied from log-edit (or git-committer-email - (git-repo-config "user.email") + (git-config "user.email") (and (boundp 'add-log-mailing-address) add-log-mailing-address) (and (fboundp 'user-mail-address) (user-mail-address)) (and (boundp 'user-mail-address) user-mail-address))) @@ -298,9 +298,9 @@ and returns the process output as a string." (git-get-string-sha1 (git-call-process-env-string nil "rev-parse" rev))) -(defun git-repo-config (key) +(defun git-config (key) "Retrieve the value associated to KEY in the git repository config file." - (let ((str (git-call-process-env-string nil "repo-config" key))) + (let ((str (git-call-process-env-string nil "config" key))) (and str (car (split-string str "\n"))))) (defun git-symbolic-ref (ref) diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview index 3b6bdceeeb..521b2fcd32 100755 --- a/contrib/gitview/gitview +++ b/contrib/gitview/gitview @@ -497,7 +497,7 @@ class GitView: fp.close() def get_encoding(self): - fp = os.popen("git repo-config --get i18n.commitencoding") + fp = os.popen("git config --get i18n.commitencoding") self.encoding=string.strip(fp.readline()) fp.close() if (self.encoding == ""): diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh index b996996bfb..dc09eae972 100644 --- a/contrib/remotes2config.sh +++ b/contrib/remotes2config.sh @@ -26,8 +26,8 @@ if [ -d "$GIT_DIR"/remotes ]; then mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old fi ;; *) - echo "git-repo-config $key "$value" $regex" - git-repo-config $key "$value" $regex || error=1 ;; + echo "git-config $key "$value" $regex" + git-config $key "$value" $regex || error=1 ;; esac done fi diff --git a/git-clone.sh b/git-clone.sh index ced7dfba3e..1531da52cb 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -36,7 +36,7 @@ clone_dumb_http () { clone_tmp="$GIT_DIR/clone-tmp" && mkdir -p "$clone_tmp" || exit 1 if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-repo-config --bool http.noEPSV`" = true ]; then + "`git-config --bool http.noEPSV`" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi http_fetch "$1/info/refs" "$clone_tmp/refs" || @@ -386,17 +386,17 @@ then git-update-ref HEAD "$head_sha1" && # Upstream URL - git-repo-config remote."$origin".url "$repo" && + git-config remote."$origin".url "$repo" && # Set up the mappings to track the remote branches. - git-repo-config remote."$origin".fetch \ + git-config remote."$origin".fetch \ "+refs/heads/*:$remote_top/*" '^$' && rm -f "refs/remotes/$origin/HEAD" git-symbolic-ref "refs/remotes/$origin/HEAD" \ "refs/remotes/$origin/$head_points_at" && - git-repo-config branch."$head_points_at".remote "$origin" && - git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at" + git-config branch."$head_points_at".remote "$origin" && + git-config branch."$head_points_at".merge "refs/heads/$head_points_at" esac case "$no_checkout" in diff --git a/git-commit.sh b/git-commit.sh index d8c236b240..85c278afab 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -429,7 +429,7 @@ then fi elif test "$use_commit" != "" then - encoding=$(git repo-config i18n.commitencoding || echo UTF-8) + encoding=$(git config i18n.commitencoding || echo UTF-8) git show -s --pretty=raw --encoding="$encoding" "$use_commit" | sed -e '1,/^$/d' -e 's/^ //' elif test -f "$GIT_DIR/MERGE_MSG" @@ -485,7 +485,7 @@ then q } ' - encoding=$(git repo-config i18n.commitencoding || echo UTF-8) + encoding=$(git config i18n.commitencoding || echo UTF-8) set_author_env=`git show -s --pretty=raw --encoding="$encoding" "$use_commit" | LANG=C LC_ALL=C sed -ne "$pick_author_script"` eval "$set_author_env" diff --git a/git-cvsserver.perl b/git-cvsserver.perl index e18e901731..9371788fab 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -172,11 +172,11 @@ sub req_Root return 0; } - my @gitvars = `git-repo-config -l`; + my @gitvars = `git-config -l`; if ($?) { - print "E problems executing git-repo-config on the server -- this is not a git repository or the PATH is not set correctly.\n"; + print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n"; print "E \n"; - print "error 1 - problem executing git-repo-config\n"; + print "error 1 - problem executing git-config\n"; return 0; } foreach my $line ( @gitvars ) diff --git a/git-fetch.sh b/git-fetch.sh index 61c8cf4773..c1f6e1e841 100755 --- a/git-fetch.sh +++ b/git-fetch.sh @@ -321,7 +321,7 @@ fetch_main () { curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-repo-config --bool http.noEPSV`" = true ]; then + "`git-config --bool http.noEPSV`" = true ]; then noepsv_opt="--disable-epsv" fi diff --git a/git-instaweb.sh b/git-instaweb.sh index 80adc8307b..cbc7418e35 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -15,11 +15,11 @@ case "$GIT_DIR" in fqgitdir="$PWD/$GIT_DIR" ;; esac -local="`git repo-config --bool --get instaweb.local`" -httpd="`git repo-config --get instaweb.httpd`" -browser="`git repo-config --get instaweb.browser`" -port=`git repo-config --get instaweb.port` -module_path="`git repo-config --get instaweb.modulepath`" +local="`git config --bool --get instaweb.local`" +httpd="`git config --get instaweb.httpd`" +browser="`git config --get instaweb.browser`" +port=`git config --get instaweb.port` +module_path="`git config --get instaweb.modulepath`" conf=$GIT_DIR/gitweb/httpd.conf diff --git a/git-ls-remote.sh b/git-ls-remote.sh index dd22783824..e6f574b99b 100755 --- a/git-ls-remote.sh +++ b/git-ls-remote.sh @@ -58,7 +58,7 @@ http://* | https://* | ftp://* ) curl_extra_args="-k" fi if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \ - "`git-repo-config --bool http.noEPSV`" = true ]; then + "`git-config --bool http.noEPSV`" = true ]; then curl_extra_args="${curl_extra_args} --disable-epsv" fi curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || diff --git a/git-merge.sh b/git-merge.sh index 656869101a..04a5eb0f29 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -233,7 +233,7 @@ case "$use_strategies" in '') case "$#" in 1) - var="`git-repo-config --get pull.twohead`" + var="`git-config --get pull.twohead`" if test -n "$var" then use_strategies="$var" @@ -241,7 +241,7 @@ case "$use_strategies" in use_strategies="$default_twohead_strategies" fi ;; *) - var="`git-repo-config --get pull.octopus`" + var="`git-config --get pull.octopus`" if test -n "$var" then use_strategies="$var" diff --git a/git-p4import.py b/git-p4import.py index 5c56cace0e..60a758bfe3 100644 --- a/git-p4import.py +++ b/git-p4import.py @@ -193,13 +193,13 @@ class git_command: def get_config(self, variable): try: - return self.git("repo-config --get %s" % variable)[0].rstrip() + return self.git("config --get %s" % variable)[0].rstrip() except: return None def set_config(self, variable, value): try: - self.git("repo-config %s %s"%(variable, value) ) + self.git("config %s %s"%(variable, value) ) except: die("Could not set %s to " % variable, value) diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 7e87f2e06e..9d269671de 100755 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -10,7 +10,7 @@ get_data_source () { echo '' ;; *) - if test "$(git-repo-config --get "remote.$1.url")" + if test "$(git-config --get "remote.$1.url")" then echo config elif test -f "$GIT_DIR/remotes/$1" @@ -32,7 +32,7 @@ get_remote_url () { echo "$1" ;; config) - git-repo-config --get "remote.$1.url" + git-config --get "remote.$1.url" ;; remotes) sed -ne '/^URL: */{ @@ -50,7 +50,7 @@ get_remote_url () { get_default_remote () { curr_branch=$(git-symbolic-ref -q HEAD | sed -e 's|^refs/heads/||') - origin=$(git-repo-config --get "branch.$curr_branch.remote") + origin=$(git-config --get "branch.$curr_branch.remote") echo ${origin:-origin} } @@ -60,7 +60,7 @@ get_remote_default_refs_for_push () { '' | branches) ;; # no default push mapping, just send matching refs. config) - git-repo-config --get-all "remote.$1.push" ;; + git-config --get-all "remote.$1.push" ;; remotes) sed -ne '/^Push: */{ s///p @@ -146,7 +146,7 @@ canon_refs_list_for_fetch () { then curr_branch=$(git-symbolic-ref -q HEAD | \ sed -e 's|^refs/heads/||') - merge_branches=$(git-repo-config \ + merge_branches=$(git-config \ --get-all "branch.${curr_branch}.merge") fi if test -z "$merge_branches" && test $is_explicit != explicit @@ -212,7 +212,7 @@ get_remote_default_refs_for_fetch () { echo "HEAD:" ;; config) canon_refs_list_for_fetch -d "$1" \ - $(git-repo-config --get-all "remote.$1.fetch") ;; + $(git-config --get-all "remote.$1.fetch") ;; branches) remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1") case "$remote_branch" in '') remote_branch=master ;; esac @@ -291,7 +291,7 @@ get_uploadpack () { data_source=$(get_data_source "$1") case "$data_source" in config) - uplp=$(git-repo-config --get "remote.$1.uploadpack") + uplp=$(git-config --get "remote.$1.uploadpack") echo ${uplp:-git-upload-pack} ;; *) diff --git a/git-remote.perl b/git-remote.perl index fc055b6d95..c813fe1451 100755 --- a/git-remote.perl +++ b/git-remote.perl @@ -64,7 +64,7 @@ sub list_remote { my ($git) = @_; my %seen = (); my @remotes = eval { - $git->command(qw(repo-config --get-regexp), '^remote\.'); + $git->command(qw(config --get-regexp), '^remote\.'); }; for (@remotes) { if (/^remote\.([^.]*)\.(\S*)\s+(.*)$/) { @@ -103,7 +103,7 @@ sub list_branch { my ($git) = @_; my %seen = (); my @branches = eval { - $git->command(qw(repo-config --get-regexp), '^branch\.'); + $git->command(qw(config --get-regexp), '^branch\.'); }; for (@branches) { if (/^branch\.([^.]*)\.(\S*)\s+(.*)$/) { @@ -238,8 +238,8 @@ sub add_remote { print STDERR "remote $name already exists.\n"; exit(1); } - $git->command('repo-config', "remote.$name.url", $url); - $git->command('repo-config', "remote.$name.fetch", + $git->command('config', "remote.$name.url", $url); + $git->command('config', "remote.$name.fetch", "+refs/heads/*:refs/remotes/$name/*"); } diff --git a/git-repack.sh b/git-repack.sh index da8e67f7a5..ddfa8b44a1 100755 --- a/git-repack.sh +++ b/git-repack.sh @@ -28,7 +28,7 @@ done # Later we will default repack.UseDeltaBaseOffset to true default_dbo=false -case "`git repo-config --bool repack.usedeltabaseoffset || +case "`git config --bool repack.usedeltabaseoffset || echo $default_dbo`" in true) extra="$extra --delta-base-offset" ;; diff --git a/git-revert.sh b/git-revert.sh index bb8f1ca24a..866d622d23 100755 --- a/git-revert.sh +++ b/git-revert.sh @@ -81,7 +81,7 @@ prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) || git-rev-parse --verify "$commit^2" >/dev/null 2>&1 && die "Cannot run $me a multi-parent commit." -encoding=$(git repo-config i18n.commitencoding || echo UTF-8) +encoding=$(git config i18n.commitencoding || echo UTF-8) # "commit" is an existing commit. We would want to apply # the difference it introduces since its first parent "prev" diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 6b1c1423eb..b4aa4b2f4e 100755 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -29,7 +29,7 @@ set_reflog_action() { } is_bare_repository () { - git-repo-config --bool --get core.bare || + git-config --bool --get core.bare || case "$GIT_DIR" in .git | */.git) echo false ;; *) echo true ;; diff --git a/git-svn.perl b/git-svn.perl index 83ec03d478..68156fc8a5 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -593,7 +593,7 @@ sub multi_init { "$trunk_url ($_trunk)\n"; } init($trunk_url); - command_noisy('repo-config', 'svn.trunk', $trunk_url); + command_noisy('config', 'svn.trunk', $trunk_url); } } $_prefix = '' unless defined $_prefix; @@ -772,22 +772,22 @@ sub log_use_color { return 1 if $_color; my ($dc, $dcvar); $dcvar = 'color.diff'; - $dc = `git-repo-config --get $dcvar`; + $dc = `git-config --get $dcvar`; if ($dc eq '') { # nothing at all; fallback to "diff.color" $dcvar = 'diff.color'; - $dc = `git-repo-config --get $dcvar`; + $dc = `git-config --get $dcvar`; } chomp($dc); if ($dc eq 'auto') { my $pc; - $pc = `git-repo-config --get color.pager`; + $pc = `git-config --get color.pager`; if ($pc eq '') { # does not have it -- fallback to pager.color - $pc = `git-repo-config --bool --get pager.color`; + $pc = `git-config --bool --get pager.color`; } else { - $pc = `git-repo-config --bool --get color.pager`; + $pc = `git-config --bool --get color.pager`; if ($?) { $pc = 'false'; } @@ -800,7 +800,7 @@ sub log_use_color { } return 0 if $dc eq 'never'; return 1 if $dc eq 'always'; - chomp($dc = `git-repo-config --bool --get $dcvar`); + chomp($dc = `git-config --bool --get $dcvar`); return ($dc eq 'true'); } @@ -919,7 +919,7 @@ sub complete_url_ls_init { waitpid $pid, 0; croak $? if $?; my ($n) = ($switch =~ /^--(\w+)/); - command_noisy('repo-config', "svn.$n", $full_url); + command_noisy('config', "svn.$n", $full_url); } sub common_prefix { @@ -1594,7 +1594,7 @@ sub init_vars { %tree_map = (); } -# convert GetOpt::Long specs for use by git-repo-config +# convert GetOpt::Long specs for use by git-config sub read_repo_config { return unless -d $GIT_DIR; my $opts = shift; @@ -1602,7 +1602,7 @@ sub read_repo_config { my $v = $opts->{$o}; my ($key) = ($o =~ /^([a-z\-]+)/); $key =~ s/-//g; - my $arg = 'git-repo-config'; + my $arg = 'git-config'; $arg .= ' --int' if ($o =~ /[:=]i$/); $arg .= ' --bool' if ($o !~ /[:=][sfi]$/); if (ref $v eq 'ARRAY') { diff --git a/git.c b/git.c index e9febc389a..d21e5e505c 100644 --- a/git.c +++ b/git.c @@ -224,6 +224,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "check-ref-format", cmd_check_ref_format }, { "cherry", cmd_cherry, RUN_SETUP }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, + { "config", cmd_config }, { "count-objects", cmd_count_objects, RUN_SETUP }, { "describe", cmd_describe, RUN_SETUP }, { "diff", cmd_diff, RUN_SETUP | USE_PAGER }, @@ -254,7 +255,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "push", cmd_push, RUN_SETUP }, { "read-tree", cmd_read_tree, RUN_SETUP }, { "reflog", cmd_reflog, RUN_SETUP }, - { "repo-config", cmd_repo_config }, + { "repo-config", cmd_config }, { "rerere", cmd_rerere, RUN_SETUP }, { "rev-list", cmd_rev_list, RUN_SETUP }, { "rev-parse", cmd_rev_parse, RUN_SETUP }, diff --git a/gitk b/gitk index 031c829f26..31d0aad450 100755 --- a/gitk +++ b/gitk @@ -6193,7 +6193,7 @@ set wrcomcmd "git diff-tree --stdin -p --pretty" set gitencoding {} catch { - set gitencoding [exec git repo-config --get i18n.commitencoding] + set gitencoding [exec git config --get i18n.commitencoding] } if {$gitencoding == ""} { set gitencoding "utf-8" diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 88af2e6380..b606c1d3e7 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -986,7 +986,7 @@ sub git_get_project_config { $key =~ s/^gitweb\.//; return if ($key =~ m/\W/); - my @x = (git_cmd(), 'repo-config'); + my @x = (git_cmd(), 'config'); if (defined $type) { push @x, $type; } push @x, "--get"; push @x, "gitweb.$key"; diff --git a/ident.c b/ident.c index 6de7eeae4d..a6fc7b5e11 100644 --- a/ident.c +++ b/ident.c @@ -178,8 +178,8 @@ static const char *env_hint = "\n" "Run\n" "\n" -" git repo-config user.email \"you@email.com\"\n" -" git repo-config user.name \"Your Name\"\n" +" git config user.email \"you@email.com\"\n" +" git config user.name \"Your Name\"\n" "\n" "To set the identity in this repository.\n" "Add --global to set your account\'s default\n" diff --git a/perl/Git.pm b/perl/Git.pm index c1729bafd2..5d1ccaa125 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -482,14 +482,14 @@ sub wc_chdir { =item config ( VARIABLE ) -Retrieve the configuration C in the same manner as C +Retrieve the configuration C in the same manner as C does. In scalar context requires the variable to be set only one time (exception is thrown otherwise), in array context returns allows the variable to be set multiple times and returns all the values. Must be called on a repository instance. -This currently wraps command('repo-config') so it is not so fast. +This currently wraps command('config') so it is not so fast. =cut @@ -500,9 +500,9 @@ sub config { try { if (wantarray) { - return $self->command('repo-config', '--get-all', $var); + return $self->command('config', '--get-all', $var); } else { - return $self->command_oneline('repo-config', '--get', $var); + return $self->command_oneline('config', '--get', $var); } } catch Git::Error::Command with { my $E = shift; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 0e4f32d5c9..49b5666b33 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -3,13 +3,13 @@ # Copyright (c) 2005 Johannes Schindelin # -test_description='Test git-repo-config in different settings' +test_description='Test git-config in different settings' . ./test-lib.sh test -f .git/config && rm .git/config -git-repo-config core.penguin "little blue" +git-config core.penguin "little blue" cat > expect << EOF [core] @@ -18,7 +18,7 @@ EOF test_expect_success 'initial' 'cmp .git/config expect' -git-repo-config Core.Movie BadPhysics +git-config Core.Movie BadPhysics cat > expect << EOF [core] @@ -28,7 +28,7 @@ EOF test_expect_success 'mixed case' 'cmp .git/config expect' -git-repo-config Cores.WhatEver Second +git-config Cores.WhatEver Second cat > expect << EOF [core] @@ -40,7 +40,7 @@ EOF test_expect_success 'similar section' 'cmp .git/config expect' -git-repo-config CORE.UPPERCASE true +git-config CORE.UPPERCASE true cat > expect << EOF [core] @@ -54,10 +54,10 @@ EOF test_expect_success 'similar section' 'cmp .git/config expect' test_expect_success 'replace with non-match' \ - 'git-repo-config core.penguin kingpin !blue' + 'git-config core.penguin kingpin !blue' test_expect_success 'replace with non-match (actually matching)' \ - 'git-repo-config core.penguin "very blue" !kingpin' + 'git-config core.penguin "very blue" !kingpin' cat > expect << EOF [core] @@ -86,7 +86,7 @@ EOF cp .git/config .git/config2 test_expect_success 'multiple unset' \ - 'git-repo-config --unset-all beta.haha' + 'git-config --unset-all beta.haha' cat > expect << EOF [beta] ; silly comment # another comment @@ -102,7 +102,7 @@ test_expect_success 'multiple unset is correct' 'cmp .git/config expect' mv .git/config2 .git/config test_expect_success '--replace-all' \ - 'git-repo-config --replace-all beta.haha gamma' + 'git-config --replace-all beta.haha gamma' cat > expect << EOF [beta] ; silly comment # another comment @@ -116,7 +116,7 @@ EOF test_expect_success 'all replaced' 'cmp .git/config expect' -git-repo-config beta.haha alpha +git-config beta.haha alpha cat > expect << EOF [beta] ; silly comment # another comment @@ -130,7 +130,7 @@ EOF test_expect_success 'really mean test' 'cmp .git/config expect' -git-repo-config nextsection.nonewline wow +git-config nextsection.nonewline wow cat > expect << EOF [beta] ; silly comment # another comment @@ -145,8 +145,8 @@ EOF test_expect_success 'really really mean test' 'cmp .git/config expect' -test_expect_success 'get value' 'test alpha = $(git-repo-config beta.haha)' -git-repo-config --unset beta.haha +test_expect_success 'get value' 'test alpha = $(git-config beta.haha)' +git-config --unset beta.haha cat > expect << EOF [beta] ; silly comment # another comment @@ -160,7 +160,7 @@ EOF test_expect_success 'unset' 'cmp .git/config expect' -git-repo-config nextsection.NoNewLine "wow2 for me" "for me$" +git-config nextsection.NoNewLine "wow2 for me" "for me$" cat > expect << EOF [beta] ; silly comment # another comment @@ -176,18 +176,18 @@ EOF test_expect_success 'multivar' 'cmp .git/config expect' test_expect_success 'non-match' \ - 'git-repo-config --get nextsection.nonewline !for' + 'git-config --get nextsection.nonewline !for' test_expect_success 'non-match value' \ - 'test wow = $(git-repo-config --get nextsection.nonewline !for)' + 'test wow = $(git-config --get nextsection.nonewline !for)' test_expect_failure 'ambiguous get' \ - 'git-repo-config --get nextsection.nonewline' + 'git-config --get nextsection.nonewline' test_expect_success 'get multivar' \ - 'git-repo-config --get-all nextsection.nonewline' + 'git-config --get-all nextsection.nonewline' -git-repo-config nextsection.nonewline "wow3" "wow$" +git-config nextsection.nonewline "wow3" "wow$" cat > expect << EOF [beta] ; silly comment # another comment @@ -202,15 +202,15 @@ EOF test_expect_success 'multivar replace' 'cmp .git/config expect' -test_expect_failure 'ambiguous value' 'git-repo-config nextsection.nonewline' +test_expect_failure 'ambiguous value' 'git-config nextsection.nonewline' test_expect_failure 'ambiguous unset' \ - 'git-repo-config --unset nextsection.nonewline' + 'git-config --unset nextsection.nonewline' test_expect_failure 'invalid unset' \ - 'git-repo-config --unset somesection.nonewline' + 'git-config --unset somesection.nonewline' -git-repo-config --unset nextsection.nonewline "wow3$" +git-config --unset nextsection.nonewline "wow3$" cat > expect << EOF [beta] ; silly comment # another comment @@ -224,12 +224,12 @@ EOF test_expect_success 'multivar unset' 'cmp .git/config expect' -test_expect_failure 'invalid key' 'git-repo-config inval.2key blabla' +test_expect_failure 'invalid key' 'git-config inval.2key blabla' -test_expect_success 'correct key' 'git-repo-config 123456.a123 987' +test_expect_success 'correct key' 'git-config 123456.a123 987' test_expect_success 'hierarchical section' \ - 'git-repo-config Version.1.2.3eX.Alpha beta' + 'git-config Version.1.2.3eX.Alpha beta' cat > expect << EOF [beta] ; silly comment # another comment @@ -255,7 +255,7 @@ version.1.2.3eX.alpha=beta EOF test_expect_success 'working --list' \ - 'git-repo-config --list > output && cmp output expect' + 'git-config --list > output && cmp output expect' cat > expect << EOF beta.noindent sillyValue @@ -263,9 +263,9 @@ nextsection.nonewline wow2 for me EOF test_expect_success '--get-regexp' \ - 'git-repo-config --get-regexp in > output && cmp output expect' + 'git-config --get-regexp in > output && cmp output expect' -git-repo-config --add nextsection.nonewline "wow4 for you" +git-config --add nextsection.nonewline "wow4 for you" cat > expect << EOF wow2 for me @@ -273,7 +273,7 @@ wow4 for you EOF test_expect_success '--add' \ - 'git-repo-config --get-all nextsection.nonewline > output && cmp output expect' + 'git-config --get-all nextsection.nonewline > output && cmp output expect' cat > .git/config << EOF [novalue] @@ -281,9 +281,9 @@ cat > .git/config << EOF EOF test_expect_success 'get variable with no value' \ - 'git-repo-config --get novalue.variable ^$' + 'git-config --get novalue.variable ^$' -git-repo-config > output 2>&1 +git-config > output 2>&1 test_expect_success 'no arguments, but no crash' \ "test $? = 129 && grep usage output" @@ -293,7 +293,7 @@ cat > .git/config << EOF c = d EOF -git-repo-config a.x y +git-config a.x y cat > expect << EOF [a.b] @@ -304,8 +304,8 @@ EOF test_expect_success 'new section is partial match of another' 'cmp .git/config expect' -git-repo-config b.x y -git-repo-config a.b c +git-config b.x y +git-config a.b c cat > expect << EOF [a.b] @@ -328,11 +328,11 @@ cat > expect << EOF ein.bahn=strasse EOF -GIT_CONFIG=other-config git-repo-config -l > output +GIT_CONFIG=other-config git-config -l > output test_expect_success 'alternative GIT_CONFIG' 'cmp output expect' -GIT_CONFIG=other-config git-repo-config anwohner.park ausweis +GIT_CONFIG=other-config git-config anwohner.park ausweis cat > expect << EOF [ein] @@ -355,7 +355,7 @@ weird EOF test_expect_success "rename section" \ - "git-repo-config --rename-section branch.eins branch.zwei" + "git-config --rename-section branch.eins branch.zwei" cat > expect << EOF # Hallo @@ -371,12 +371,12 @@ EOF test_expect_success "rename succeeded" "diff -u expect .git/config" test_expect_failure "rename non-existing section" \ - 'git-repo-config --rename-section branch."world domination" branch.drei' + 'git-config --rename-section branch."world domination" branch.drei' test_expect_success "rename succeeded" "diff -u expect .git/config" test_expect_success "rename another section" \ - 'git-repo-config --rename-section branch."1 234 blabl/a" branch.drei' + 'git-config --rename-section branch."1 234 blabl/a" branch.drei' cat > expect << EOF # Hallo @@ -393,20 +393,20 @@ test_expect_success "rename succeeded" "diff -u expect .git/config" test_expect_success numbers ' - git-repo-config kilo.gram 1k && - git-repo-config mega.ton 1m && - k=$(git-repo-config --int --get kilo.gram) && + git-config kilo.gram 1k && + git-config mega.ton 1m && + k=$(git-config --int --get kilo.gram) && test z1024 = "z$k" && - m=$(git-repo-config --int --get mega.ton) && + m=$(git-config --int --get mega.ton) && test z1048576 = "z$m" ' rm .git/config -git-repo-config quote.leading " test" -git-repo-config quote.ending "test " -git-repo-config quote.semicolon "test;test" -git-repo-config quote.hash "test#test" +git-config quote.leading " test" +git-config quote.ending "test " +git-config quote.semicolon "test;test" +git-config quote.hash "test#test" cat > expect << EOF [quote] @@ -418,10 +418,10 @@ EOF test_expect_success 'quoting' 'cmp .git/config expect' -test_expect_failure 'key with newline' 'git repo-config key.with\\\ +test_expect_failure 'key with newline' 'git config key.with\\\ newline 123' -test_expect_success 'value with newline' 'git repo-config key.sub value.with\\\ +test_expect_success 'value with newline' 'git config key.sub value.with\\\ newline' cat > .git/config <<\EOF @@ -440,7 +440,7 @@ section.noncont=not continued section.quotecont=cont;inued EOF -git repo-config --list > result +git config --list > result test_expect_success 'value continued on next line' 'cmp result expect' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index e48e2b7189..d0aba2c2ae 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -93,8 +93,8 @@ rm -rf .git/$m .git/logs expect test_expect_success \ 'enable core.logAllRefUpdates' \ - 'git-repo-config core.logAllRefUpdates true && - test true = $(git-repo-config --bool --get core.logAllRefUpdates)' + 'git-config core.logAllRefUpdates true && + test true = $(git-config --bool --get core.logAllRefUpdates)' test_expect_success \ "create $m (logged by config)" \ diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 8e8d526ef2..47d124732c 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -71,7 +71,7 @@ test_expect_success setup ' check_fsck && chmod +x C && - ( test "`git repo-config --bool core.filemode`" != false || + ( test "`git config --bool core.filemode`" != false || echo executable >>C ) && git add C && test_tick && git commit -m dragon && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index bb80e4286a..5565c27033 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -94,7 +94,7 @@ test_expect_failure \ git-branch r && git-branch -m q r/q' -git-repo-config branch.s/s.dummy Hello +git-config branch.s/s.dummy Hello test_expect_success \ 'git branch -m s/s s should work when s/t is deleted' \ @@ -107,8 +107,8 @@ test_expect_success \ test -f .git/logs/refs/heads/s' test_expect_success 'config information was renamed, too' \ - "test $(git-repo-config branch.s.dummy) = Hello && - ! git-repo-config branch.s/s/dummy" + "test $(git-config branch.s.dummy) = Hello && + ! git-config branch.s/s/dummy" test_expect_failure \ 'git-branch -m u v should fail when the reflog for u is a symlink' \ diff --git a/t/t3700-add.sh b/t/t3700-add.sh index e98786de32..caaab26c2f 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -21,7 +21,7 @@ test_expect_success \ test_expect_success \ 'git-add: Test that executable bit is not used if core.filemode=0' \ - 'git repo-config core.filemode 0 && + 'git config core.filemode 0 && echo foo >xfoo1 && chmod 755 xfoo1 && git-add xfoo1 && @@ -32,7 +32,7 @@ test_expect_success \ test_expect_success \ 'git-update-index --add: Test that executable bit is not used...' \ - 'git repo-config core.filemode 0 && + 'git config core.filemode 0 && echo foo >xfoo2 && chmod 755 xfoo2 && git-update-index --add xfoo2 && @@ -43,7 +43,7 @@ test_expect_success \ test_expect_success \ 'git-update-index --add: Test that executable bit is not used...' \ - 'git repo-config core.filemode 0 && + 'git config core.filemode 0 && ln -s xfoo2 xfoo3 && git-update-index --add xfoo3 && case "`git-ls-files --stage xfoo3`" in diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index 6714b0dd6e..e54fe0f401 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -29,7 +29,7 @@ test_expect_success 'no encoding header for base case' ' for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "$H setup" ' - git-repo-config i18n.commitencoding $H && + git-config i18n.commitencoding $H && git-checkout -b $H C0 && echo $H >F && git-commit -a -F ../t3900/$H.txt @@ -44,16 +44,16 @@ do ' done -test_expect_success 'repo-config to remove customization' ' - git-repo-config --unset-all i18n.commitencoding && - if Z=$(git-repo-config --get-all i18n.commitencoding) +test_expect_success 'config to remove customization' ' + git-config --unset-all i18n.commitencoding && + if Z=$(git-config --get-all i18n.commitencoding) then echo Oops, should have failed. false else test z = "z$Z" fi && - git-repo-config i18n.commitencoding utf-8 + git-config i18n.commitencoding utf-8 ' test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' @@ -67,9 +67,9 @@ do ' done -test_expect_success 'repo-config to add customization' ' - git-repo-config --unset-all i18n.commitencoding && - if Z=$(git-repo-config --get-all i18n.commitencoding) +test_expect_success 'config to add customization' ' + git-config --unset-all i18n.commitencoding && + if Z=$(git-config --get-all i18n.commitencoding) then echo Oops, should have failed. false @@ -81,13 +81,13 @@ test_expect_success 'repo-config to add customization' ' for H in ISO-8859-1 EUCJP ISO-2022-JP do test_expect_success "$H should be shown in itself now" ' - git-repo-config i18n.commitencoding '$H' && + git-config i18n.commitencoding '$H' && compare_with '$H' ../t3900/'$H'.txt ' done -test_expect_success 'repo-config to tweak customization' ' - git-repo-config i18n.logoutputencoding utf-8 +test_expect_success 'config to tweak customization' ' + git-config i18n.logoutputencoding utf-8 ' test_expect_success 'ISO-8859-1 should be shown in UTF-8 now' ' @@ -103,7 +103,7 @@ done for J in EUCJP ISO-2022-JP do - git-repo-config i18n.logoutputencoding $J + git-config i18n.logoutputencoding $J for H in EUCJP ISO-2022-JP do test_expect_success "$H should be shown in $J now" ' diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index eda0e2d729..a881797bc7 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -31,7 +31,7 @@ check_encoding () { } test_expect_success setup ' - git-repo-config i18n.commitencoding UTF-8 && + git-config i18n.commitencoding UTF-8 && # use UTF-8 in author and committer name to match the # i18n.commitencoding settings @@ -55,7 +55,7 @@ test_expect_success setup ' git commit -s -m "Second on side" && # the second one on the side branch is ISO-8859-1 - git-repo-config i18n.commitencoding ISO-8859-1 && + git-config i18n.commitencoding ISO-8859-1 && # use author and committer name in ISO-8859-1 to match it. . ../t3901-8859-1.txt && test_tick && @@ -64,11 +64,11 @@ test_expect_success setup ' git commit -s -m "Third on side" && # Back to default - git-repo-config i18n.commitencoding UTF-8 + git-config i18n.commitencoding UTF-8 ' test_expect_success 'format-patch output (ISO-8859-1)' ' - git-repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.logoutputencoding ISO-8859-1 && git format-patch --stdout master..HEAD^ >out-l1 && git format-patch --stdout HEAD^ >out-l2 && @@ -79,7 +79,7 @@ test_expect_success 'format-patch output (ISO-8859-1)' ' ' test_expect_success 'format-patch output (UTF-8)' ' - git repo-config i18n.logoutputencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && git format-patch --stdout master..HEAD^ >out-u1 && git format-patch --stdout HEAD^ >out-u2 && @@ -91,13 +91,13 @@ test_expect_success 'format-patch output (UTF-8)' ' test_expect_success 'rebase (U/U)' ' # We want the result of rebase in UTF-8 - git-repo-config i18n.commitencoding UTF-8 && + git-config i18n.commitencoding UTF-8 && # The test is about logoutputencoding not affecting the # final outcome -- it is used internally to generate the # patch and the log. - git repo-config i18n.logoutputencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && # The result will be committed by GIT_COMMITTER_NAME -- # we want UTF-8 encoded name. @@ -109,8 +109,8 @@ test_expect_success 'rebase (U/U)' ' ' test_expect_success 'rebase (U/L)' ' - git-repo-config i18n.commitencoding UTF-8 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && git reset --hard side && @@ -121,8 +121,8 @@ test_expect_success 'rebase (U/L)' ' test_expect_success 'rebase (L/L)' ' # In this test we want ISO-8859-1 encoded commits as the result - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && git reset --hard side && @@ -134,8 +134,8 @@ test_expect_success 'rebase (L/L)' ' test_expect_success 'rebase (L/U)' ' # This is pathological -- use UTF-8 as intermediate form # to get ISO-8859-1 results. - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding UTF-8 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && git reset --hard side && @@ -147,8 +147,8 @@ test_expect_success 'rebase (L/U)' ' test_expect_success 'cherry-pick(U/U)' ' # Both the commitencoding and logoutputencoding is set to UTF-8. - git-repo-config i18n.commitencoding UTF-8 && - git repo-config i18n.logoutputencoding UTF-8 && + git-config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && . ../t3901-utf8.txt && git reset --hard master && @@ -162,8 +162,8 @@ test_expect_success 'cherry-pick(U/U)' ' test_expect_success 'cherry-pick(L/L)' ' # Both the commitencoding and logoutputencoding is set to ISO-8859-1 - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && git reset --hard master && @@ -177,8 +177,8 @@ test_expect_success 'cherry-pick(L/L)' ' test_expect_success 'cherry-pick(U/L)' ' # Commitencoding is set to UTF-8 but logoutputencoding is ISO-8859-1 - git-repo-config i18n.commitencoding UTF-8 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && git reset --hard master && @@ -193,8 +193,8 @@ test_expect_success 'cherry-pick(L/U)' ' # Again, the commitencoding is set to ISO-8859-1 but # logoutputencoding is set to UTF-8. - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding UTF-8 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && git reset --hard master && @@ -206,8 +206,8 @@ test_expect_success 'cherry-pick(L/U)' ' ' test_expect_success 'rebase --merge (U/U)' ' - git-repo-config i18n.commitencoding UTF-8 && - git repo-config i18n.logoutputencoding UTF-8 && + git-config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding UTF-8 && . ../t3901-utf8.txt && git reset --hard side && @@ -217,8 +217,8 @@ test_expect_success 'rebase --merge (U/U)' ' ' test_expect_success 'rebase --merge (U/L)' ' - git-repo-config i18n.commitencoding UTF-8 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding UTF-8 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-utf8.txt && git reset --hard side && @@ -229,8 +229,8 @@ test_expect_success 'rebase --merge (U/L)' ' test_expect_success 'rebase --merge (L/L)' ' # In this test we want ISO-8859-1 encoded commits as the result - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding ISO-8859-1 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding ISO-8859-1 && . ../t3901-8859-1.txt && git reset --hard side && @@ -242,8 +242,8 @@ test_expect_success 'rebase --merge (L/L)' ' test_expect_success 'rebase --merge (L/U)' ' # This is pathological -- use UTF-8 as intermediate form # to get ISO-8859-1 results. - git-repo-config i18n.commitencoding ISO-8859-1 && - git repo-config i18n.logoutputencoding UTF-8 && + git-config i18n.commitencoding ISO-8859-1 && + git config i18n.logoutputencoding UTF-8 && . ../t3901-8859-1.txt && git reset --hard side && diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh index 67b9681d36..9c58d77cc2 100755 --- a/t/t4000-diff-format.sh +++ b/t/t4000-diff-format.sh @@ -28,7 +28,7 @@ test_expect_success \ 'git-diff-files -p >current' # that's as far as it comes -if [ "$(git repo-config --get core.filemode)" = false ] +if [ "$(git config --get core.filemode)" = false ] then say 'filemode disabled on the filesystem' test_done diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index 8ad69d1115..ca342f48a1 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -15,7 +15,7 @@ test_expect_success \ tree=`git-write-tree` && echo $tree' -if [ "$(git repo-config --get core.filemode)" = false ] +if [ "$(git config --get core.filemode)" = false ] then say 'filemode disabled on the filesystem, using update-index --chmod=+x' test_expect_success \ diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index ed37141b6e..3d85ceaae9 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -73,7 +73,7 @@ test_expect_success setup ' for i in 1 2; do echo $i; done >>dir/sub && git update-index file0 dir/sub && - git repo-config log.showroot false && + git config log.showroot false && git commit --amend && git show-branch ' diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index 22da6a00cc..b4662b0364 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -31,7 +31,7 @@ test_expect_success setup \ test_expect_success apply \ 'git-apply --index --stat --summary --apply test-patch' -if [ "$(git repo-config --get core.filemode)" = false ] +if [ "$(git config --get core.filemode)" = false ] then say 'filemode disabled on the filesystem' else diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 5a7232a577..a6dbb04a86 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -30,19 +30,19 @@ test_expect_success \ test_expect_success \ 'verify-pack -v, packedGitWindowSize == 1 page' \ - 'git-repo-config core.packedGitWindowSize 512 && + 'git-config core.packedGitWindowSize 512 && git-verify-pack -v "$pack1"' test_expect_success \ 'verify-pack -v, packedGit{WindowSize,Limit} == 1 page' \ - 'git-repo-config core.packedGitWindowSize 512 && - git-repo-config core.packedGitLimit 512 && + 'git-config core.packedGitWindowSize 512 && + git-config core.packedGitLimit 512 && git-verify-pack -v "$pack1"' test_expect_success \ 'repack -a -d, packedGit{WindowSize,Limit} == 1 page' \ - 'git-repo-config core.packedGitWindowSize 512 && - git-repo-config core.packedGitLimit 512 && + 'git-config core.packedGitWindowSize 512 && + git-config core.packedGitLimit 512 && commit2=`git-commit-tree $tree -p $commit1 > log2.txt && - git repo-config transfer.unpacklimit 0 + git config transfer.unpacklimit 0 ) add A1 diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 3ce9446210..50c64856f0 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -22,14 +22,14 @@ test_expect_success "clone and setup child repos" ' cd .. && git clone . two && cd two && - git repo-config branch.master.remote one && - git repo-config remote.one.url ../one/.git/ && - git repo-config remote.one.fetch refs/heads/master:refs/heads/one && + git config branch.master.remote one && + git config remote.one.url ../one/.git/ && + git config remote.one.fetch refs/heads/master:refs/heads/one && cd .. && git clone . three && cd three && - git repo-config branch.master.remote two && - git repo-config branch.master.merge refs/heads/one && + git config branch.master.remote two && + git config branch.master.merge refs/heads/one && mkdir -p .git/remotes && { echo "URL: ../two/.git/" diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 63e49f310c..ea14023616 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -108,7 +108,7 @@ EOF test_expect_success 'merge-msg test #3' ' - git repo-config merge.summary true && + git config merge.summary true && git checkout master && setdate && @@ -138,7 +138,7 @@ EOF test_expect_success 'merge-msg test #4' ' - git repo-config merge.summary true && + git config merge.summary true && git checkout master && setdate && @@ -150,7 +150,7 @@ test_expect_success 'merge-msg test #4' ' test_expect_success 'merge-msg test #5' ' - git repo-config merge.summary yes && + git config merge.summary yes && git checkout master && setdate && From df391b192d285646fe80ca4d3cfe3c0a3beb5989 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 28 Jan 2007 16:33:58 -0800 Subject: [PATCH 47/47] git-fsck-objects is now synonym to git-fsck Signed-off-by: Junio C Hamano --- .gitignore | 1 + Documentation/cmd-list.perl | 2 +- Documentation/core-intro.txt | 2 +- Documentation/everyday.txt | 4 +- Documentation/git-fsck-objects.txt | 128 +----------------------- Documentation/git-fsck.txt | 139 +++++++++++++++++++++++++++ Documentation/git-pack-redundant.txt | 2 +- Documentation/git-prune.txt | 2 +- Makefile | 3 +- fsck-objects.c => fsck.c | 2 +- git-lost-found.sh | 2 +- http-fetch.c | 2 +- t/t1410-reflog.sh | 2 +- t/t5500-fetch-pack.sh | 6 +- t/t5710-info-alternate.sh | 2 +- 15 files changed, 159 insertions(+), 140 deletions(-) create mode 100644 Documentation/git-fsck.txt rename fsck-objects.c => fsck.c (99%) diff --git a/.gitignore b/.gitignore index b4dccd7b81..a43444fb92 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ git-findtags git-fmt-merge-msg git-for-each-ref git-format-patch +git-fsck git-fsck-objects git-gc git-get-tar-commit-id diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 824462551f..6dba8d8fe0 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -97,7 +97,7 @@ git-fetch-pack synchingrepositories git-fmt-merge-msg purehelpers git-for-each-ref plumbinginterrogators git-format-patch mainporcelain -git-fsck-objects ancillaryinterrogators +git-fsck ancillaryinterrogators git-gc mainporcelain git-get-tar-commit-id ancillaryinterrogators git-grep mainporcelain diff --git a/Documentation/core-intro.txt b/Documentation/core-intro.txt index 0458dc3d02..abafefc71c 100644 --- a/Documentation/core-intro.txt +++ b/Documentation/core-intro.txt @@ -82,7 +82,7 @@ size> + + . The structured objects can further have their structure and connectivity to other objects verified. This is generally done with -the `git-fsck-objects` program, which generates a full dependency graph +the `git-fsck` program, which generates a full dependency graph of all objects, and verifies their internal consistency (in addition to just verifying their superficial consistency through the hash). diff --git a/Documentation/everyday.txt b/Documentation/everyday.txt index fbbbc92b81..08c61b1f1a 100644 --- a/Documentation/everyday.txt +++ b/Documentation/everyday.txt @@ -28,7 +28,7 @@ Everybody uses these commands to maintain git repositories. * gitlink:git-init[1] or gitlink:git-clone[1] to create a new repository. - * gitlink:git-fsck-objects[1] to check the repository for errors. + * gitlink:git-fsck[1] to check the repository for errors. * gitlink:git-prune[1] to remove unused objects in the repository. @@ -43,7 +43,7 @@ Examples Check health and remove cruft.:: + ------------ -$ git fsck-objects <1> +$ git fsck <1> $ git count-objects <2> $ git repack <3> $ git gc <4> diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.txt index d0af99d351..f21061ecfe 100644 --- a/Documentation/git-fsck-objects.txt +++ b/Documentation/git-fsck-objects.txt @@ -8,132 +8,10 @@ git-fsck-objects - Verifies the connectivity and validity of the objects in the SYNOPSIS -------- -[verse] -'git-fsck-objects' [--tags] [--root] [--unreachable] [--cache] - [--full] [--strict] [*] +'git-fsck-objects' ... DESCRIPTION ----------- -Verifies the connectivity and validity of the objects in the database. - -OPTIONS -------- -:: - An object to treat as the head of an unreachability trace. -+ -If no objects are given, git-fsck-objects defaults to using the -index file and all SHA1 references in .git/refs/* as heads. - ---unreachable:: - Print out objects that exist but that aren't readable from any - of the reference nodes. - ---root:: - Report root nodes. - ---tags:: - Report tags. - ---cache:: - Consider any object recorded in the index also as a head node for - an unreachability trace. - ---full:: - Check not just objects in GIT_OBJECT_DIRECTORY - ($GIT_DIR/objects), but also the ones found in alternate - object pools listed in GIT_ALTERNATE_OBJECT_DIRECTORIES - or $GIT_DIR/objects/info/alternates, - and in packed git archives found in $GIT_DIR/objects/pack - and corresponding pack subdirectories in alternate - object pools. - ---strict:: - Enable more strict checking, namely to catch a file mode - recorded with g+w bit set, which was created by older - versions of git. Existing repositories, including the - Linux kernel, git itself, and sparse repository have old - objects that triggers this check, but it is recommended - to check new projects with this flag. - -It tests SHA1 and general object sanity, and it does full tracking of -the resulting reachability and everything else. It prints out any -corruption it finds (missing or bad objects), and if you use the -'--unreachable' flag it will also print out objects that exist but -that aren't readable from any of the specified head nodes. - -So for example - - git-fsck-objects --unreachable HEAD $(cat .git/refs/heads/*) - -will do quite a _lot_ of verification on the tree. There are a few -extra validity tests to be added (make sure that tree objects are -sorted properly etc), but on the whole if "git-fsck-objects" is happy, you -do have a valid tree. - -Any corrupt objects you will have to find in backups or other archives -(i.e., you can just remove them and do an "rsync" with some other site in -the hopes that somebody else has the object you have corrupted). - -Of course, "valid tree" doesn't mean that it wasn't generated by some -evil person, and the end result might be crap. git is a revision -tracking system, not a quality assurance system ;) - -Extracted Diagnostics ---------------------- - -expect dangling commits - potential heads - due to lack of head information:: - You haven't specified any nodes as heads so it won't be - possible to differentiate between un-parented commits and - root nodes. - -missing sha1 directory '':: - The directory holding the sha1 objects is missing. - -unreachable :: - The object , isn't actually referred to directly - or indirectly in any of the trees or commits seen. This can - mean that there's another root node that you're not specifying - or that the tree is corrupt. If you haven't missed a root node - then you might as well delete unreachable nodes since they - can't be used. - -missing :: - The object , is referred to but isn't present in - the database. - -dangling :: - The object , is present in the database but never - 'directly' used. A dangling commit could be a root node. - -warning: git-fsck-objects: tree has full pathnames in it:: - And it shouldn't... - -sha1 mismatch :: - The database has an object who's sha1 doesn't match the - database value. - This indicates a serious data integrity problem. - -Environment Variables ---------------------- - -GIT_OBJECT_DIRECTORY:: - used to specify the object database root (usually $GIT_DIR/objects) - -GIT_INDEX_FILE:: - used to specify the index file of the index - -GIT_ALTERNATE_OBJECT_DIRECTORIES:: - used to specify additional object database roots (usually unset) - -Author ------- -Written by Linus Torvalds - -Documentation --------------- -Documentation by David Greaves, Junio C Hamano and the git-list . - -GIT ---- -Part of the gitlink:git[7] suite +This is a synonym for gitlink:git-fsck[1]. Please refer to the +documentation of that command. diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt new file mode 100644 index 0000000000..058009d2fa --- /dev/null +++ b/Documentation/git-fsck.txt @@ -0,0 +1,139 @@ +git-fsck(1) +=========== + +NAME +---- +git-fsck - Verifies the connectivity and validity of the objects in the database + + +SYNOPSIS +-------- +[verse] +'git-fsck' [--tags] [--root] [--unreachable] [--cache] + [--full] [--strict] [*] + +DESCRIPTION +----------- +Verifies the connectivity and validity of the objects in the database. + +OPTIONS +------- +:: + An object to treat as the head of an unreachability trace. ++ +If no objects are given, git-fsck defaults to using the +index file and all SHA1 references in .git/refs/* as heads. + +--unreachable:: + Print out objects that exist but that aren't readable from any + of the reference nodes. + +--root:: + Report root nodes. + +--tags:: + Report tags. + +--cache:: + Consider any object recorded in the index also as a head node for + an unreachability trace. + +--full:: + Check not just objects in GIT_OBJECT_DIRECTORY + ($GIT_DIR/objects), but also the ones found in alternate + object pools listed in GIT_ALTERNATE_OBJECT_DIRECTORIES + or $GIT_DIR/objects/info/alternates, + and in packed git archives found in $GIT_DIR/objects/pack + and corresponding pack subdirectories in alternate + object pools. + +--strict:: + Enable more strict checking, namely to catch a file mode + recorded with g+w bit set, which was created by older + versions of git. Existing repositories, including the + Linux kernel, git itself, and sparse repository have old + objects that triggers this check, but it is recommended + to check new projects with this flag. + +It tests SHA1 and general object sanity, and it does full tracking of +the resulting reachability and everything else. It prints out any +corruption it finds (missing or bad objects), and if you use the +'--unreachable' flag it will also print out objects that exist but +that aren't readable from any of the specified head nodes. + +So for example + + git-fsck --unreachable HEAD $(cat .git/refs/heads/*) + +will do quite a _lot_ of verification on the tree. There are a few +extra validity tests to be added (make sure that tree objects are +sorted properly etc), but on the whole if "git-fsck" is happy, you +do have a valid tree. + +Any corrupt objects you will have to find in backups or other archives +(i.e., you can just remove them and do an "rsync" with some other site in +the hopes that somebody else has the object you have corrupted). + +Of course, "valid tree" doesn't mean that it wasn't generated by some +evil person, and the end result might be crap. git is a revision +tracking system, not a quality assurance system ;) + +Extracted Diagnostics +--------------------- + +expect dangling commits - potential heads - due to lack of head information:: + You haven't specified any nodes as heads so it won't be + possible to differentiate between un-parented commits and + root nodes. + +missing sha1 directory '':: + The directory holding the sha1 objects is missing. + +unreachable :: + The object , isn't actually referred to directly + or indirectly in any of the trees or commits seen. This can + mean that there's another root node that you're not specifying + or that the tree is corrupt. If you haven't missed a root node + then you might as well delete unreachable nodes since they + can't be used. + +missing :: + The object , is referred to but isn't present in + the database. + +dangling :: + The object , is present in the database but never + 'directly' used. A dangling commit could be a root node. + +warning: git-fsck: tree has full pathnames in it:: + And it shouldn't... + +sha1 mismatch :: + The database has an object who's sha1 doesn't match the + database value. + This indicates a serious data integrity problem. + +Environment Variables +--------------------- + +GIT_OBJECT_DIRECTORY:: + used to specify the object database root (usually $GIT_DIR/objects) + +GIT_INDEX_FILE:: + used to specify the index file of the index + +GIT_ALTERNATE_OBJECT_DIRECTORIES:: + used to specify additional object database roots (usually unset) + +Author +------ +Written by Linus Torvalds + +Documentation +-------------- +Documentation by David Greaves, Junio C Hamano and the git-list . + +GIT +--- +Part of the gitlink:git[7] suite + diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.txt index be2c64eb57..94bbea0db2 100644 --- a/Documentation/git-pack-redundant.txt +++ b/Documentation/git-pack-redundant.txt @@ -21,7 +21,7 @@ given will be ignored when checking which packs are required. This makes the following command useful when wanting to remove packs which contain unreachable objects. -git-fsck-objects --full --unreachable | cut -d ' ' -f3 | \ +git-fsck --full --unreachable | cut -d ' ' -f3 | \ git-pack-redundant --all | xargs rm OPTIONS diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt index a11e303094..0b44f3015d 100644 --- a/Documentation/git-prune.txt +++ b/Documentation/git-prune.txt @@ -13,7 +13,7 @@ SYNOPSIS DESCRIPTION ----------- -This runs `git-fsck-objects --unreachable` using all the refs +This runs `git-fsck --unreachable` using all the refs available in `$GIT_DIR/refs`, optionally with additional set of objects specified on the command line, and prunes all objects unreachable from any of these head objects from the object database. diff --git a/Makefile b/Makefile index fd8a522efa..1552b2a530 100644 --- a/Makefile +++ b/Makefile @@ -192,7 +192,7 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ - git-convert-objects$X git-fetch-pack$X git-fsck-objects$X \ + git-convert-objects$X git-fetch-pack$X git-fsck$X \ git-hash-object$X git-index-pack$X git-local-fetch$X \ git-merge-base$X \ git-daemon$X \ @@ -214,6 +214,7 @@ EXTRA_PROGRAMS = BUILT_INS = \ git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \ git-get-tar-commit-id$X git-init$X git-repo-config$X \ + git-fsck-objects$X \ $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) # what 'all' will build and 'install' will install, in gitexecdir diff --git a/fsck-objects.c b/fsck.c similarity index 99% rename from fsck-objects.c rename to fsck.c index ecfb014fff..558f0a6b34 100644 --- a/fsck-objects.c +++ b/fsck.c @@ -606,7 +606,7 @@ int main(int argc, char **argv) continue; } if (*arg == '-') - usage("git-fsck-objects [--tags] [--root] [[--unreachable] [--cache] [--full] [--strict] *]"); + usage("git-fsck [--tags] [--root] [[--unreachable] [--cache] [--full] [--strict] *]"); } fsck_head_link(); diff --git a/git-lost-found.sh b/git-lost-found.sh index b928f2ca52..9360804711 100755 --- a/git-lost-found.sh +++ b/git-lost-found.sh @@ -12,7 +12,7 @@ fi laf="$GIT_DIR/lost-found" rm -fr "$laf" && mkdir -p "$laf/commit" "$laf/other" || exit -git fsck-objects --full | +git fsck --full | while read dangling type sha1 do case "$dangling" in diff --git a/http-fetch.c b/http-fetch.c index efd494a47f..9f790a08e5 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1069,7 +1069,7 @@ int main(int argc, const char **argv) fprintf(stderr, "Some loose object were found to be corrupt, but they might be just\n" "a false '404 Not Found' error message sent with incorrect HTTP\n" -"status code. Suggest running git fsck-objects.\n"); +"status code. Suggest running git-fsck.\n"); } return rc; } diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 47d124732c..e5bbc384f7 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -20,7 +20,7 @@ check_have () { } check_fsck () { - output=$(git fsck-objects --full) + output=$(git fsck --full) case "$1" in '') test -z "$output" ;; diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index e35d60fa3a..48e3d1705f 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -63,13 +63,13 @@ pull_to_client () { case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac git-symbolic-ref HEAD refs/heads/`echo $heads | sed -e 's/^\(.\).*$/\1/'` - test_expect_success "fsck" 'git-fsck-objects --full > fsck.txt 2>&1' + test_expect_success "fsck" 'git-fsck --full > fsck.txt 2>&1' test_expect_success 'check downloaded results' \ 'mv .git/objects/pack/pack-* . && p=`ls -1 pack-*.pack` && git-unpack-objects <$p && - git-fsck-objects --full' + git-fsck --full' test_expect_success "new object count after $number pull" \ 'idx=`echo pack-*.idx` && @@ -145,7 +145,7 @@ test_expect_success "clone shallow object count (part 2)" ' ' test_expect_success "fsck in shallow repo" \ - "(cd shallow; git-fsck-objects --full)" + "(cd shallow; git-fsck --full)" #test_done; exit diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh index b9f6d96363..2f8e97cb7e 100755 --- a/t/t5710-info-alternate.sh +++ b/t/t5710-info-alternate.sh @@ -17,7 +17,7 @@ reachable_via() { } test_valid_repo() { - git fsck-objects --full > fsck.log && + git fsck --full > fsck.log && test `wc -l < fsck.log` = 0 }