diff options
82 files changed, 1052 insertions, 411 deletions
diff --git a/Documentation/RelNotes-1.7.0.7.txt b/Documentation/RelNotes-1.7.0.7.txt new file mode 100644 index 000000000..d0cb7ca7e --- /dev/null +++ b/Documentation/RelNotes-1.7.0.7.txt @@ -0,0 +1,16 @@ +Git v1.7.0.7 Release Notes +========================== + +Fixes since v1.7.0.6 +-------------------- + + * "make NO_CURL=NoThanks install" was broken. + + * An overlong line after ".gitdir: " in a git file caused out of bounds + access to an array on the stack. + + * "git config --path conf.var" to attempt to expand a variable conf.var + that uses "~/" short-hand segfaulted when $HOME environment variable + was not set. + +And other minor fixes and documentation updates. diff --git a/Documentation/RelNotes-1.7.1.2.txt b/Documentation/RelNotes-1.7.1.2.txt index 46b6a960c..61ba14e26 100644 --- a/Documentation/RelNotes-1.7.1.2.txt +++ b/Documentation/RelNotes-1.7.1.2.txt @@ -17,3 +17,12 @@ Fixes since v1.7.1.1 * "git rev-parse --parseopt --stop-at-non-option" did not stop at non option when --keep-dashdash was in effect. + + * An overlong line after ".gitdir: " in a git file caused out of bounds + access to an array on the stack. + + * "git config --path conf.var" to attempt to expand a variable conf.var + that uses "~/" short-hand segfaulted when $HOME environment variable + was not set. + +And other minor fixes and documentation updates. diff --git a/Documentation/RelNotes-1.7.2.1.txt b/Documentation/RelNotes-1.7.2.1.txt new file mode 100644 index 000000000..1103c47a4 --- /dev/null +++ b/Documentation/RelNotes-1.7.2.1.txt @@ -0,0 +1,25 @@ +Git v1.7.2.1 Release Notes +========================== + +Fixes since v1.7.2 +------------------ + + * "git instaweb" wasn't useful when your Apache was installed under a + name other than apache2 (e.g. "httpd"). + + * Similarly, "git web--browse" (invoked by "git help -w") learned that + chrome browser is sometimes called google-chrome. + + * An overlong line after ".gitdir: " in a git file caused out of bounds + access to an array on the stack. + + * "git config --path conf.var" to attempt to expand a variable conf.var + that uses "~/" short-hand segfaulted when $HOME environment variable + was not set. + + * Documentation on Cygwin failed to build. + + * The error message from "git pull blarg" when 'blarg' is an unknown + remote name has been improved. + +And other minor fixes and documentation updates. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index eb53e0636..ece3c7748 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -7,17 +7,16 @@ Checklist (and a short version for the impatient): before committing - do not check in commented out code or unneeded files - the first line of the commit message should be a short - description and should skip the full stop + description (50 characters is the soft limit, see DISCUSSION + in git-commit(1)), and should skip the full stop - the body should provide a meaningful commit message, which: - uses the imperative, present tense: "change", not "changed" or "changes". - includes motivation for the change, and contrasts its implementation with previous behaviour - - if you want your work included in git.git, add a - "Signed-off-by: Your Name <you@example.com>" line to the - commit message (or just use the option "-s" when - committing) to confirm that you agree to the Developer's - Certificate of Origin + - add a "Signed-off-by: Your Name <you@example.com>" line to the + commit message (or just use the option "-s" when committing) + to confirm that you agree to the Developer's Certificate of Origin - make sure that you have tests for the bug you are fixing - make sure that the test suite passes after your commit diff --git a/Documentation/config.txt b/Documentation/config.txt index e75434b3e..f81fb918d 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -1558,6 +1558,10 @@ receive.denyDeletes:: If set to true, git-receive-pack will deny a ref update that deletes the ref. Use this to prevent such a ref deletion via a push. +receive.denyDeleteCurrent:: + If set to true, git-receive-pack will deny a ref update that + deletes the currently checked out branch of a non-bare repository. + receive.denyCurrentBranch:: If set to true or "refuse", git-receive-pack will deny a ref update to the currently checked out branch of a non-bare repository. diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 2371262b1..eecedaab6 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -206,10 +206,29 @@ endif::git-format-patch[] the diff-patch output format. Non default number of digits can be specified with `--abbrev=<n>`. --B:: - Break complete rewrite changes into pairs of delete and create. - --M:: +-B[<n>][/<m>]:: + Break complete rewrite changes into pairs of delete and + create. This serves two purposes: ++ +It affects the way a change that amounts to a total rewrite of a file +not as a series of deletion and insertion mixed together with a very +few lines that happen to match textually as the context, but as a +single deletion of everything old followed by a single insertion of +everything new, and the number `m` controls this aspect of the -B +option (defaults to 60%). `-B/70%` specifies that less than 30% of the +original should remain in the result for git to consider it a total +rewrite (i.e. otherwise the resulting patch will be a series of +deletion and insertion mixed together with context lines). ++ +When used with -M, a totally-rewritten file is also considered as the +source of a rename (usually -M only considers a file that disappeared +as the source of a rename), and the number `n` controls this aspect of +the -B option (defaults to 50%). `-B20%` specifies that a change with +addition and deletion compared to 20% or more of the file's size are +eligible for being picked up as a possible source of a rename to +another file. + +-M[<n>]:: ifndef::git-log[] Detect renames. endif::git-log[] @@ -218,9 +237,15 @@ ifdef::git-log[] For following files across renames while traversing history, see `--follow`. endif::git-log[] + If `n` is specified, it is a is a threshold on the similarity + index (i.e. amount of addition/deletions compared to the + file's size). For example, `-M90%` means git should consider a + delete/add pair to be a rename if more than 90% of the file + hasn't changed. --C:: +-C[<n>]:: Detect copies as well as renames. See also `--find-copies-harder`. + If `n` is specified, it has the same meaning as for `-M<n>`. ifndef::git-format-patch[] --diff-filter=[ACDMRTUXB*]:: diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index 8463439ac..4a74b23d4 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -26,6 +26,10 @@ with the `--cache` option the patch is only applied to the index. Without these options, the command applies the patch only to files, and does not require them to be in a git repository. +This command applies the patch but does not create a commit. Use +linkgit:git-am[1] to create commits from patches generated by +linkgit:git-format-patch[1] and/or received by email. + OPTIONS ------- <patch>...:: @@ -242,6 +246,12 @@ If `--index` is not specified, then the submodule commits in the patch are ignored and only the absence or presence of the corresponding subdirectory is checked and (if possible) updated. + +SEE ALSO +-------- +linkgit:git-am[1]. + + Author ------ Written by Linus Torvalds <torvalds@osdl.org> diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.txt index 2c3c4d299..e70cea932 100644 --- a/Documentation/git-instaweb.txt +++ b/Documentation/git-instaweb.txt @@ -49,15 +49,18 @@ OPTIONS linkgit:git-web--browse[1] for more information about this. If the script fails, the URL will be printed to stdout. +start:: --start:: Start the httpd instance and exit. This does not generate any of the configuration files for spawning a new instance. +stop:: --stop:: Stop the httpd instance and exit. This does not generate any of the configuration files for spawning a new instance, nor does it close the browser. +restart:: --restart:: Restart the httpd instance and exit. This does not generate any of the configuration files for spawning a new instance. diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index e970664fe..c213bdbdc 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -55,6 +55,9 @@ OPTIONS paths. With this, the full diff is shown for commits that touch the specified paths; this means that "<path>..." limits only commits, and doesn't limit diff for those commits. ++ +Note that this affects all diff-based output types, e.g. those +produced by --stat etc. --log-size:: Before the log message print out its size in bytes. Intended diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index 3521637b5..a7c8174d0 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -106,8 +106,16 @@ OPTIONS with `-s` or `-u` options does not make any sense. -t:: - Identify the file status with the following tags (followed by - a space) at the start of each line: + This feature is semi-deprecated. For scripting purpose, + linkgit:git-status[1] `--porcelain` and + linkgit:git-diff-files[1] `--name-status` are almost always + superior alternatives, and users should look at + linkgit:git-status[1] `--short` or linkgit:git-diff[1] + `--name-status` for more user-friendly alternatives. ++ +This option identifies the file status with the following tags (followed by +a space) at the start of each line: + H:: cached S:: skip-worktree M:: unmerged @@ -132,6 +140,12 @@ OPTIONS lines, show only a partial prefix. Non default number of digits can be specified with --abbrev=<n>. +--debug:: + After each line that describes a file, add more data about its + cache entry. This is intended to show as much information as + possible for manual inspection; the exact format may change at + any time. + \--:: Do not interpret any more arguments as options. diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index 5540af5d1..2981d8c5e 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -129,10 +129,12 @@ OPTIONS is taken to be in `refs/notes/` if it is not qualified. -n:: +--dry-run:: Do not remove anything; just report the object names whose notes would be removed. -v:: +--verbose:: Report all object names whose notes are removed. diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.txt index 15cfb7a8d..4d673a568 100644 --- a/Documentation/git-prune.txt +++ b/Documentation/git-prune.txt @@ -31,10 +31,12 @@ OPTIONS ------- -n:: +--dry-run:: Do not remove anything; just report what it would remove. -v:: +--verbose:: Report all removed objects. \--:: diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index b68abff28..658ff2ff6 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -200,16 +200,29 @@ summary:: For a successfully pushed ref, the summary shows the old and new values of the ref in a form suitable for using as an argument to `git log` (this is `<old>..<new>` in most cases, and - `<old>...<new>` for forced non-fast-forward updates). For a - failed update, more details are given for the failure. - The string `rejected` indicates that git did not try to send the - ref at all (typically because it is not a fast-forward). The - string `remote rejected` indicates that the remote end refused - the update; this rejection is typically caused by a hook on the - remote side. The string `remote failure` indicates that the - remote end did not report the successful update of the ref - (perhaps because of a temporary error on the remote side, a - break in the network connection, or other transient error). + `<old>...<new>` for forced non-fast-forward updates). ++ +For a failed update, more details are given: ++ +-- +rejected:: + Git did not try to send the ref at all, typically because it + is not a fast-forward and you did not force the update. + +remote rejected:: + The remote end refused the update. Usually caused by a hook + on the remote side, or because the remote repository has one + of the following safety options in effect: + `receive.denyCurrentBranch` (for pushes to the checked out + branch), `receive.denyNonFastForwards` (for forced + non-fast-forward updates), `receive.denyDeletes` or + `receive.denyDeleteCurrent`. See linkgit:git-config[1]. + +remote failure:: + The remote end did not report the successful update of the ref, + perhaps because of a temporary error on the remote side, a + break in the network connection, or other transient error. +-- from:: The name of the local ref being pushed, minus its diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index f6037c4f6..2e78da448 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -412,6 +412,13 @@ turn `core.sparseCheckout` on in order to have sparse checkout support. +BUGS +---- +In order to match a directory with $GIT_DIR/info/sparse-checkout, +trailing slash must be used. The form without trailing slash, while +works with .gitignore, does not work with sparse checkout. + + SEE ALSO -------- linkgit:git-write-tree[1]; linkgit:git-ls-files[1]; diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.txt index 19335fdda..400f61f6e 100644 --- a/Documentation/git-request-pull.txt +++ b/Documentation/git-request-pull.txt @@ -7,7 +7,7 @@ git-request-pull - Generates a summary of pending changes SYNOPSIS -------- -'git request-pull' <start> <url> [<end>] +'git request-pull' [-p] <start> <url> [<end>] DESCRIPTION ----------- @@ -17,6 +17,9 @@ the given URL in the generated summary. OPTIONS ------- +-p:: + Show patch text + <start>:: Commit to start at. diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 645f0c174..b04d129b3 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -8,40 +8,50 @@ git-reset - Reset current HEAD to the specified state SYNOPSIS -------- [verse] -'git reset' [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>] 'git reset' [-q] [<commit>] [--] <paths>... 'git reset' --patch [<commit>] [--] [<paths>...] +'git reset' [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>] DESCRIPTION ----------- -Sets the current head to the specified commit and optionally resets the -index and working tree to match. - -This command is useful if you notice some small error in a recent -commit (or set of commits) and want to redo that part without showing -the undo in the history. - -If you want to undo a commit other than the latest on a branch, -linkgit:git-revert[1] is your friend. - -The second and third forms with 'paths' and/or --patch are used to -revert selected paths in the index from a given commit, without moving -HEAD. - +In the first and second form, copy entries from <commit> to the index. +In the third form, set the current branch to <commit>, optionally +modifying index and worktree to match. The <commit> defaults to HEAD +in all forms. + +'git reset' [-q] [<commit>] [--] <paths>...:: + This form resets the index entries for all <paths> to their + state at the <commit>. (It does not affect the worktree, nor + the current branch.) ++ +This means that `git reset <paths>` is the opposite of `git add +<paths>`. -OPTIONS -------- ---mixed:: - Resets the index but not the working tree (i.e., the changed files - are preserved but not marked for commit) and reports what has not - been updated. This is the default action. +'git reset' --patch|-p [<commit>] [--] [<paths>...]:: + Interactively select hunks in the difference between the index + and <commit> (defaults to HEAD). The chosen hunks are applied + in reverse to the index. ++ +This means that `git reset -p` is the opposite of `git add -p` (see +linkgit:git-add[1]). +'git reset' [--<mode>] [<commit>]:: + This form points the current branch to <commit> and then + updates index and working tree according to <mode>, which must + be one of the following: ++ +-- --soft:: Does not touch the index file nor the working tree at all, but requires them to be in a good order. This leaves all your changed files "Changes to be committed", as 'git status' would put it. +--mixed:: + Resets the index but not the working tree (i.e., the changed files + are preserved but not marked for commit) and reports what has not + been updated. This is the default action. + --hard:: Matches the working tree and index to that of the tree being switched to. Any changes to tracked files in the working tree @@ -59,132 +69,46 @@ OPTIONS the given commit. If a file that is different between the current commit and the given commit has local changes, reset is aborted. +-- --p:: ---patch:: - Interactively select hunks in the difference between the index - and <commit> (defaults to HEAD). The chosen hunks are applied - in reverse to the index. -+ -This means that `git reset -p` is the opposite of `git add -p` (see -linkgit:git-add[1]). +If you want to undo a commit other than the latest on a branch, +linkgit:git-revert[1] is your friend. + + +OPTIONS +------- -q:: --quiet:: Be quiet, only report errors. -<commit>:: - Commit to make the current HEAD. If not given defaults to HEAD. - -DISCUSSION ----------- -The tables below show what happens when running: - ----------- -git reset --option target ----------- - -to reset the HEAD to another commit (`target`) with the different -reset options depending on the state of the files. - -In these tables, A, B, C and D are some different states of a -file. For example, the first line of the first table means that if a -file is in state A in the working tree, in state B in the index, in -state C in HEAD and in state D in the target, then "git reset --soft -target" will put the file in state A in the working tree, in state B -in the index and in state D in HEAD. - - working index HEAD target working index HEAD - ---------------------------------------------------- - A B C D --soft A B D - --mixed A D D - --hard D D D - --merge (disallowed) - --keep (disallowed) - - working index HEAD target working index HEAD - ---------------------------------------------------- - A B C C --soft A B C - --mixed A C C - --hard C C C - --merge (disallowed) - --keep A C C - - working index HEAD target working index HEAD - ---------------------------------------------------- - B B C D --soft B B D - --mixed B D D - --hard D D D - --merge D D D - --keep (disallowed) - - working index HEAD target working index HEAD - ---------------------------------------------------- - B B C C --soft B B C - --mixed B C C - --hard C C C - --merge C C C - --keep B C C - - working index HEAD target working index HEAD - ---------------------------------------------------- - B C C D --soft B C D - --mixed B D D - --hard D D D - --merge (disallowed) - --keep (disallowed) - - working index HEAD target working index HEAD - ---------------------------------------------------- - B C C C --soft B C C - --mixed B C C - --hard C C C - --merge B C C - --keep B C C - -"reset --merge" is meant to be used when resetting out of a conflicted -merge. Any mergy operation guarantees that the work tree file that is -involved in the merge does not have local change wrt the index before -it starts, and that it writes the result out to the work tree. So if -we see some difference between the index and the target and also -between the index and the work tree, then it means that we are not -resetting out from a state that a mergy operation left after failing -with a conflict. That is why we disallow --merge option in this case. - -"reset --keep" is meant to be used when removing some of the last -commits in the current branch while keeping changes in the working -tree. If there could be conflicts between the changes in the commit we -want to remove and the changes in the working tree we want to keep, -the reset is disallowed. That's why it is disallowed if there are both -changes between the working tree and HEAD, and between HEAD and the -target. To be safe, it is also disallowed when there are unmerged -entries. - -The following tables show what happens when there are unmerged -entries: - - working index HEAD target working index HEAD - ---------------------------------------------------- - X U A B --soft (disallowed) - --mixed X B B - --hard B B B - --merge B B B - --keep (disallowed) - - working index HEAD target working index HEAD - ---------------------------------------------------- - X U A A --soft (disallowed) - --mixed X A A - --hard A A A - --merge A A A - --keep (disallowed) - -X means any state and U means an unmerged index. - -Examples +EXAMPLES -------- +Undo add:: ++ +------------ +$ edit <1> +$ git add frotz.c filfre.c +$ mailx <2> +$ git reset <3> +$ git pull git://info.example.com/ nitfol <4> +------------ ++ +<1> You are happily working on something, and find the changes +in these files are in good order. You do not want to see them +when you run "git diff", because you plan to work on other files +and changes with these files are distracting. +<2> Somebody asks you to pull, and the changes sounds worthy of merging. +<3> However, you already dirtied the index (i.e. your index does +not match the HEAD commit). But you know the pull you are going +to make does not affect frotz.c nor filfre.c, so you revert the +index changes for these two files. Your changes in working tree +remain there. +<4> Then you can pull and merge, leaving frotz.c and filfre.c +changes still in the working tree. + Undo a commit and redo:: + ------------ @@ -204,19 +128,6 @@ edit the message further, you can give -C option instead. + See also the --amend option to linkgit:git-commit[1]. -Undo commits permanently:: -+ ------------- -$ git commit ... -$ git reset --hard HEAD~3 <1> ------------- -+ -<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad -and you do not want to ever see them again. Do *not* do this if -you have already given these commits to somebody else. (See the -"RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for -the implications of doing so.) - Undo a commit, making it a topic branch:: + ------------ @@ -232,28 +143,18 @@ current HEAD. <2> Rewind the master branch to get rid of those three commits. <3> Switch to "topic/wip" branch and keep working. -Undo add:: +Undo commits permanently:: + ------------ -$ edit <1> -$ git add frotz.c filfre.c -$ mailx <2> -$ git reset <3> -$ git pull git://info.example.com/ nitfol <4> +$ git commit ... +$ git reset --hard HEAD~3 <1> ------------ + -<1> You are happily working on something, and find the changes -in these files are in good order. You do not want to see them -when you run "git diff", because you plan to work on other files -and changes with these files are distracting. -<2> Somebody asks you to pull, and the changes sounds worthy of merging. -<3> However, you already dirtied the index (i.e. your index does -not match the HEAD commit). But you know the pull you are going -to make does not affect frotz.c nor filfre.c, so you revert the -index changes for these two files. Your changes in working tree -remain there. -<4> Then you can pull and merge, leaving frotz.c and filfre.c -changes still in the working tree. +<1> The last three commits (HEAD, HEAD^, and HEAD~2) were bad +and you do not want to ever see them again. Do *not* do this if +you have already given these commits to somebody else. (See the +"RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for +the implications of doing so.) Undo a merge or pull:: + @@ -376,6 +277,114 @@ $ git reset --keep start <3> <3> But you can use "reset --keep" to remove the unwanted commit after you switched to "branch2". + +DISCUSSION +---------- + +The tables below show what happens when running: + +---------- +git reset --option target +---------- + +to reset the HEAD to another commit (`target`) with the different +reset options depending on the state of the files. + +In these tables, A, B, C and D are some different states of a +file. For example, the first line of the first table means that if a +file is in state A in the working tree, in state B in the index, in +state C in HEAD and in state D in the target, then "git reset --soft +target" will put the file in state A in the working tree, in state B +in the index and in state D in HEAD. + + working index HEAD target working index HEAD + ---------------------------------------------------- + A B C D --soft A B D + --mixed A D D + --hard D D D + --merge (disallowed) + --keep (disallowed) + + working index HEAD target working index HEAD + ---------------------------------------------------- + A B C C --soft A B C + --mixed A C C + --hard C C C + --merge (disallowed) + --keep A C C + + working index HEAD target working index HEAD + ---------------------------------------------------- + B B C D --soft B B D + --mixed B D D + --hard D D D + --merge D D D + --keep (disallowed) + + working index HEAD target working index HEAD + ---------------------------------------------------- + B B C C --soft B B C + --mixed B C C + --hard C C C + --merge C C C + --keep B C C + + working index HEAD target working index HEAD + ---------------------------------------------------- + B C C D --soft B C D + --mixed B D D + --hard D D D + --merge (disallowed) + --keep (disallowed) + + working index HEAD target working index HEAD + ---------------------------------------------------- + B C C C --soft B C C + --mixed B C C + --hard C C C + --merge B C C + --keep B C C + +"reset --merge" is meant to be used when resetting out of a conflicted +merge. Any mergy operation guarantees that the work tree file that is +involved in the merge does not have local change wrt the index before +it starts, and that it writes the result out to the work tree. So if +we see some difference between the index and the target and also +between the index and the work tree, then it means that we are not +resetting out from a state that a mergy operation left after failing +with a conflict. That is why we disallow --merge option in this case. + +"reset --keep" is meant to be used when removing some of the last +commits in the current branch while keeping changes in the working +tree. If there could be conflicts between the changes in the commit we +want to remove and the changes in the working tree we want to keep, +the reset is disallowed. That's why it is disallowed if there are both +changes between the working tree and HEAD, and between HEAD and the +target. To be safe, it is also disallowed when there are unmerged +entries. + +The following tables show what happens when there are unmerged +entries: + + working index HEAD target working index HEAD + ---------------------------------------------------- + X U A B --soft (disallowed) + --mixed X B B + --hard B B B + --merge B B B + --keep (disallowed) + + working index HEAD target working index HEAD + ---------------------------------------------------- + X U A A --soft (disallowed) + --mixed X A A + --hard A A A + --merge A A A + --keep (disallowed) + +X means any state and U means an unmerged index. + + Author ------ Written by Junio C Hamano <gitster@pobox.com> and Linus Torvalds <torvalds@osdl.org> diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index 0727f431c..be4c05336 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -184,10 +184,13 @@ scripts the same facilities C builtins have. It works as an option normalizer (e.g. splits single switches aggregate values), a bit like `getopt(1)` does. It takes on the standard input the specification of the options to parse and -understand, and echoes on the standard output a line suitable for `sh(1)` `eval` +understand, and echoes on the standard output a string suitable for `sh(1)` `eval` to replace the arguments with normalized ones. In case of error, it outputs usage on the standard error stream, and exits with code 129. +Note: Make sure you quote the result when passing it to `eval`. See +below for an example. + Input Format ~~~~~~~~~~~~ @@ -244,7 +247,7 @@ bar= some cool option --bar with an argument An option group Header C? option C with an optional argument" -eval `echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?` +eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" ------------ SQ-QUOTE diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index 3f9d9c6db..75780d7d6 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -163,9 +163,15 @@ flag, so you can do to get a listing of all tags together with what they dereference. +FILES +----- +`.git/refs/*`, `.git/packed-refs` + SEE ALSO -------- -linkgit:git-ls-remote[1] +linkgit:git-ls-remote[1], +linkgit:git-update-ref[1], +linkgit:gitrepository-layout[5] AUTHORS ------- diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index b09bd9761..4b84d08fc 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -646,6 +646,12 @@ svn.brokenSymlinkWorkaround:: revision fetched. If unset, 'git svn' assumes this option to be "true". +svn.pathnameencoding:: + This instructs git svn to recode pathnames to a given encoding. + It can be used by windows users and by those who work in non-utf8 + locales to avoid corrupted file names with non-ASCII characters. + Valid encodings are the ones supported by Perl's Encode module. + Since the noMetadata, rewriteRoot, rewriteUUID, useSvnsyncProps and useSvmProps options all affect the metadata generated and used by 'git svn'; they *must* be set in the configuration file before any history is imported diff --git a/Documentation/git.txt b/Documentation/git.txt index 27ece5885..c28a7ecc4 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -44,20 +44,23 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.7.2/git.html[documentation for release 1.7.2] +* link:v1.7.2.1/git.html[documentation for release 1.7.2.1] * release notes for + link:RelNotes-1.7.2.1.txt[1.7.2.1], link:RelNotes-1.7.2.txt[1.7.2]. -* link:v1.7.1.1/git.html[documentation for release 1.7.1.1] +* link:v1.7.1.2/git.html[documentation for release 1.7.1.2] * release notes for + link:RelNotes-1.7.1.2.txt[1.7.1.2], link:RelNotes-1.7.1.1.txt[1.7.1.1], link:RelNotes-1.7.1.txt[1.7.1]. -* link:v1.7.0.6/git.html[documentation for release 1.7.0.6] +* link:v1.7.0.7/git.html[documentation for release 1.7.0.7] * release notes for + link:RelNotes-1.7.0.7.txt[1.7.0.7], link:RelNotes-1.7.0.6.txt[1.7.0.6], link:RelNotes-1.7.0.5.txt[1.7.0.5], link:RelNotes-1.7.0.4.txt[1.7.0.4], @@ -724,6 +727,13 @@ The documentation for git suite was started by David Greaves <david@dgreaves.com>, and later enhanced greatly by the contributors on the git-list <git@vger.kernel.org>. +Reporting Bugs +-------------- + +Report bugs to the Git mailing list <git@vger.kernel.org> where the +development and maintenance is primarily done. You do not have to be +subscribed to the list to send a message there. + SEE ALSO -------- linkgit:gittutorial[7], linkgit:gittutorial-2[7], diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index d78e121c7..9b6f3899e 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -1,5 +1,5 @@ --pretty[='<format>']:: ---format[='<format>']:: +--format='<format>':: Pretty-print the contents of the commit logs in a given format, where '<format>' can be one of 'oneline', 'short', 'medium', diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index e88f50caf..f6d301a10 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.7.2 +DEF_VER=v1.7.2.GIT LF=' ' @@ -157,3 +157,36 @@ Issues of note: It has been reported that docbook-xsl version 1.72 and 1.73 are buggy; 1.72 misformats manual pages for callouts, and 1.73 needs the patch in contrib/patches/docbook-xsl-manpages-charmap.patch + + Users attempting to build the documentation on Cygwin may need to ensure + that the /etc/xml/catalog file looks something like this: + + <?xml version="1.0"?> + <!DOCTYPE catalog PUBLIC + "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" + "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd" + > + <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <rewriteURI + uriStartString = "http://docbook.sourceforge.net/release/xsl/current" + rewritePrefix = "/usr/share/sgml/docbook/xsl-stylesheets" + /> + <rewriteURI + uriStartString="http://www.oasis-open.org/docbook/xml/4.5" + rewritePrefix="/usr/share/sgml/docbook/xml-dtd-4.5" + /> + </catalog> + + This can be achieved with the following two xmlcatalog commands: + + xmlcatalog --noout \ + --add rewriteURI \ + http://docbook.sourceforge.net/release/xsl/current \ + /usr/share/sgml/docbook/xsl-stylesheets \ + /etc/xml/catalog + + xmlcatalog --noout \ + --add rewriteURI \ + http://www.oasis-open.org/docbook/xml/4.5/xsl/current \ + /usr/share/sgml/docbook/xml-dtd-4.5 \ + /etc/xml/catalog @@ -1854,8 +1854,9 @@ builtin/prune.o builtin/reflog.o reachable.o: reachable.h builtin/commit.o builtin/revert.o wt-status.o: wt-status.h builtin/tar-tree.o archive-tar.o: tar.h builtin/pack-objects.o: thread-utils.h +connect.o transport.o http-backend.o: url.h http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h -http.o http-walker.o http-push.o remote-curl.o: http.h +http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h xdiff-interface.o $(XDIFF_OBJS): \ xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ @@ -2075,10 +2076,19 @@ endif bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \ execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \ { test "$$bindir/" = "$$execdir/" || \ - { $(RM) "$$execdir/git$X" && \ + for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \ + $(RM) "$$execdir/$$p" && \ test -z "$(NO_CROSS_DIRECTORY_HARDLINKS)" && \ - ln "$$bindir/git$X" "$$execdir/git$X" 2>/dev/null || \ - cp "$$bindir/git$X" "$$execdir/git$X"; } ; } && \ + ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \ + cp "$$bindir/$$p" "$$execdir/$$p" || exit; \ + done; \ + } && \ + for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \ + $(RM) "$$bindir/$$p" && \ + ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \ + cp "$$bindir/git$X" "$$bindir/$$p" || exit; \ + done && \ for p in $(BUILT_INS); do \ $(RM) "$$execdir/$$p" && \ ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ @@ -2254,6 +2264,7 @@ check-docs:: documented,gitglossary | \ documented,githooks | \ documented,gitrepository-layout | \ + documented,gitrevisions | \ documented,gittutorial | \ documented,gittutorial-2 | \ documented,git-bisect-lk2009 | \ @@ -1 +1 @@ -Documentation/RelNotes-1.7.2.txt
\ No newline at end of file +Documentation/RelNotes-1.7.2.1.txt
\ No newline at end of file @@ -7,9 +7,9 @@ #define say1(a,b) fprintf(stderr, a, b) #define say2(a,b,c) fprintf(stderr, a, b, c) #else -#define say(a) do {} while(0) -#define say1(a,b) do {} while(0) -#define say2(a,b,c) do {} while(0) +#define say(a) do { /* nothing */ } while (0) +#define say1(a,b) do { /* nothing */ } while (0) +#define say2(a,b,c) do { /* nothing */ } while (0) #endif static const char en85[] = { diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index b106c65d8..ae3f28115 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -33,28 +33,38 @@ static void collapse_slashes(char *dst, const char *src) *dst = '\0'; } +static int check_ref_format_branch(const char *arg) +{ + struct strbuf sb = STRBUF_INIT; + int nongit; + + setup_git_directory_gently(&nongit); + if (strbuf_check_branch_ref(&sb, arg)) + die("'%s' is not a valid branch name", arg); + printf("%s\n", sb.buf + 11); + return 0; +} + +static int check_ref_format_print(const char *arg) +{ + char *refname = xmalloc(strlen(arg) + 1); + + if (check_ref_format(arg)) + return 1; + collapse_slashes(refname, arg); + printf("%s\n", refname); + return 0; +} + int cmd_check_ref_format(int argc, const char **argv, const char *prefix) { if (argc == 2 && !strcmp(argv[1], "-h")) usage(builtin_check_ref_format_usage); - if (argc == 3 && !strcmp(argv[1], "--branch")) { - struct strbuf sb = STRBUF_INIT; - - if (strbuf_check_branch_ref(&sb, argv[2])) - die("'%s' is not a valid branch name", argv[2]); - printf("%s\n", sb.buf + 11); - exit(0); - } - if (argc == 3 && !strcmp(argv[1], "--print")) { - char *refname = xmalloc(strlen(argv[2]) + 1); - - if (check_ref_format(argv[2])) - exit(1); - collapse_slashes(refname, argv[2]); - printf("%s\n", refname); - exit(0); - } + if (argc == 3 && !strcmp(argv[1], "--branch")) + return check_ref_format_branch(argv[2]); + if (argc == 3 && !strcmp(argv[1], "--print")) + return check_ref_format_print(argv[2]); if (argc != 2) usage(builtin_check_ref_format_usage); return !!check_ref_format(argv[1]); diff --git a/builtin/commit.c b/builtin/commit.c index a78dbd83b..2bb30c0e8 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -147,7 +147,7 @@ static struct option builtin_commit_options[] = { "terminate entries with NUL"), OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"), - { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, + { OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, /* end commit contents options */ { OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL, diff --git a/builtin/fetch.c b/builtin/fetch.c index 6eb1dfea0..1b67f5fda 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -845,7 +845,8 @@ static int fetch_one(struct remote *remote, int argc, const char **argv) int exit_code; if (!remote) - die("Where do you want to fetch from today?"); + die("No remote repository specified. Please, specify either a URL or a\n" + "remote name from which new revisions should be fetched."); transport = transport_get(remote, NULL); transport_set_verbosity(transport, verbosity, progress); diff --git a/builtin/help.c b/builtin/help.c index a9836b00a..61ff79839 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -120,7 +120,7 @@ static void exec_woman_emacs(const char *path, const char *page) if (!path) path = "emacsclient"; strbuf_addf(&man_page, "(woman \"%s\")", page); - execlp(path, "emacsclient", "-e", man_page.buf, NULL); + execlp(path, "emacsclient", "-e", man_page.buf, (char *)NULL); warning("failed to exec '%s': %s", path, strerror(errno)); } } @@ -148,7 +148,7 @@ static void exec_man_konqueror(const char *path, const char *page) } else path = "kfmclient"; strbuf_addf(&man_page, "man:%s(1)", page); - execlp(path, filename, "newTab", man_page.buf, NULL); + execlp(path, filename, "newTab", man_page.buf, (char *)NULL); warning("failed to exec '%s': %s", path, strerror(errno)); } } @@ -157,7 +157,7 @@ static void exec_man_man(const char *path, const char *page) { if (!path) path = "man"; - execlp(path, "man", page, NULL); + execlp(path, "man", page, (char *)NULL); warning("failed to exec '%s': %s", path, strerror(errno)); } @@ -165,7 +165,7 @@ static void exec_man_cmd(const char *cmd, const char *page) { struct strbuf shell_cmd = STRBUF_INIT; strbuf_addf(&shell_cmd, "%s %s", cmd, page); - execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL); + execl("/bin/sh", "sh", "-c", shell_cmd.buf, (char *)NULL); warning("failed to exec '%s': %s", cmd, strerror(errno)); } @@ -372,7 +372,7 @@ static void show_info_page(const char *git_cmd) { const char *page = cmd_to_page(git_cmd); setenv("INFOPATH", system_path(GIT_INFO_PATH), 1); - execlp("info", "info", "gitman", page, NULL); + execlp("info", "info", "gitman", page, (char *)NULL); die("no info viewer handled the request"); } @@ -398,7 +398,7 @@ static void get_html_page_path(struct strbuf *page_path, const char *page) #ifndef open_html static void open_html(const char *path) { - execl_git_cmd("web--browse", "-c", "help.browser", path, NULL); + execl_git_cmd("web--browse", "-c", "help.browser", path, (char *)NULL); } #endif diff --git a/builtin/index-pack.c b/builtin/index-pack.c index a89ae831d..fad76bf7a 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -884,6 +884,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage(index_pack_usage); + read_replace_refs = 0; + /* * We wish to read the repository's config file if any, and * for that it is necessary to call setup_git_directory_gently(). diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 1b9b8a8b4..cc202c5f6 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -25,6 +25,7 @@ static int show_modified; static int show_killed; static int show_valid_bit; static int line_terminator = '\n'; +static int debug_mode; static const char *prefix; static int max_prefix_len; @@ -162,6 +163,13 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) ce_stage(ce)); } write_name(ce->name, ce_namelen(ce)); + if (debug_mode) { + printf(" ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec); + printf(" mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec); + printf(" dev: %d\tino: %d\n", ce->ce_dev, ce->ce_ino); + printf(" uid: %d\tgid: %d\n", ce->ce_uid, ce->ce_gid); + printf(" size: %d\tflags: %x\n", ce->ce_size, ce->ce_flags); + } } static int show_one_ru(struct string_list_item *item, void *cbdata) @@ -519,6 +527,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) OPT_STRING(0, "with-tree", &with_tree, "tree-ish", "pretend that paths removed since <tree-ish> are still present"), OPT__ABBREV(&abbrev), + OPT_BOOLEAN(0, "debug", &debug_mode, "show debugging data"), OPT_END() }; diff --git a/builtin/notes.c b/builtin/notes.c index 190005f3c..fbc347c9f 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -798,8 +798,9 @@ static int prune(int argc, const char **argv, const char *prefix) struct notes_tree *t; int show_only = 0, verbose = 0; struct option options[] = { - OPT_BOOLEAN('n', NULL, &show_only, "do not remove, show only"), - OPT_BOOLEAN('v', NULL, &verbose, "report pruned notes"), + OPT_BOOLEAN('n', "dry-run", &show_only, + "do not remove, show only"), + OPT_BOOLEAN('v', "verbose", &verbose, "report pruned notes"), OPT_END() }; diff --git a/builtin/prune.c b/builtin/prune.c index 81f915ec3..99218ba49 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -125,10 +125,9 @@ int cmd_prune(int argc, const char **argv, const char *prefix) { struct rev_info revs; const struct option options[] = { - OPT_BOOLEAN('n', NULL, &show_only, + OPT_BOOLEAN('n', "dry-run", &show_only, "do not remove, show only"), - OPT_BOOLEAN('v', NULL, &verbose, - "report pruned objects"), + OPT_BOOLEAN('v', "verbose", &verbose, "report pruned objects"), OPT_DATE(0, "expire", &expire, "expire objects older than <time>"), OPT_END() diff --git a/builtin/push.c b/builtin/push.c index f4358b9d2..e655eb769 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -22,13 +22,13 @@ static int progress; static const char **refspec; static int refspec_nr; +static int refspec_alloc; static void add_refspec(const char *ref) { - int nr = refspec_nr + 1; - refspec = xrealloc(refspec, nr * sizeof(char *)); - refspec[nr-1] = ref; - refspec_nr = nr; + refspec_nr++; + ALLOC_GROW(refspec, refspec_nr, refspec_alloc); + refspec[refspec_nr-1] = ref; } static void set_refspecs(const char **refs, int nr) @@ -130,8 +130,8 @@ static int push_with_options(struct transport *transport, int flags) if (nonfastforward && advice_push_nonfastforward) { fprintf(stderr, "To prevent you from losing history, non-fast-forward updates were rejected\n" - "Merge the remote changes before pushing again. See the 'Note about\n" - "fast-forwards' section of 'git push --help' for details.\n"); + "Merge the remote changes (e.g. 'git pull') before pushing again. See the\n" + "'Note about fast-forwards' section of 'git push --help' for details.\n"); } return 1; @@ -449,7 +449,7 @@ extern int init_db(const char *template_dir, unsigned int flags); alloc = alloc_nr(alloc); \ x = xrealloc((x), alloc * sizeof(*(x))); \ } \ - } while(0) + } while (0) /* Initialize and use the cache information */ extern int read_index(struct index_state *); @@ -811,6 +811,7 @@ const char *show_date_relative(unsigned long time, int tz, char *timebuf, size_t timebuf_size); int parse_date(const char *date, char *buf, int bufsize); +int parse_date_basic(const char *date, unsigned long *timestamp, int *offset); void datestamp(char *buf, int bufsize); #define approxidate(s) approxidate_careful((s), NULL) unsigned long approxidate_careful(const char *, int *); diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email index 30ae63d74..09c524105 100755 --- a/contrib/hooks/post-receive-email +++ b/contrib/hooks/post-receive-email @@ -203,7 +203,7 @@ generate_email_header() # Generate header cat <<-EOF To: $recipients - Subject: ${emailprefix}$projectdesc $refname_type, $short_refname, ${change_type}d. $describe + Subject: ${emailprefix}$projectdesc $refname_type $short_refname ${change_type}d. $describe X-Git-Refname: $refname X-Git-Reftype: $refname_type X-Git-Oldrev: $oldrev diff --git a/contrib/svn-fe/.gitignore b/contrib/svn-fe/.gitignore index 27a33b669..02a779158 100644 --- a/contrib/svn-fe/.gitignore +++ b/contrib/svn-fe/.gitignore @@ -1,3 +1,4 @@ /*.xml /*.1 /*.html +/svn-fe diff --git a/contrib/svn-fe/Makefile b/contrib/svn-fe/Makefile index 4cc8d1582..360d8da41 100644 --- a/contrib/svn-fe/Makefile +++ b/contrib/svn-fe/Makefile @@ -38,7 +38,7 @@ svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(GIT_LIB) $(ALL_LDFLAGS) $(LIBS) svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h - $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) $< + $(QUIET_CC)$(CC) -I../../vcs-svn -o $*.o -c $(ALL_CFLAGS) $< svn-fe.html: svn-fe.txt $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \ diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c index 43c4320ca..e9b9ba4da 100644 --- a/contrib/svn-fe/svn-fe.c +++ b/contrib/svn-fe/svn-fe.c @@ -4,7 +4,7 @@ */ #include <stdlib.h> -#include "vcs-svn/svndump.h" +#include "svndump.h" int main(int argc, char **argv) { @@ -586,7 +586,7 @@ static int date_string(unsigned long date, int offset, char *buf, int len) /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822 (i.e. English) day/month names, and it doesn't work correctly with %z. */ -int parse_date_toffset(const char *date, unsigned long *timestamp, int *offset) +int parse_date_basic(const char *date, unsigned long *timestamp, int *offset) { struct tm tm; int tm_gmt; @@ -642,17 +642,16 @@ int parse_date_toffset(const char *date, unsigned long *timestamp, int *offset) if (!tm_gmt) *timestamp -= *offset * 60; - return 1; /* success */ + return 0; /* success */ } int parse_date(const char *date, char *result, int maxlen) { unsigned long timestamp; int offset; - if (parse_date_toffset(date, ×tamp, &offset) > 0) - return date_string(timestamp, offset, result, maxlen); - else + if (parse_date_basic(date, ×tamp, &offset)) return -1; + return date_string(timestamp, offset, result, maxlen); } enum date_mode parse_date_format(const char *format) @@ -1004,9 +1003,8 @@ unsigned long approxidate_relative(const char *date, const struct timeval *tv) int offset; int errors = 0; - if (parse_date_toffset(date, ×tamp, &offset) > 0) + if (!parse_date_basic(date, ×tamp, &offset)) return timestamp; - return approxidate_str(date, tv, &errors); } @@ -1019,7 +1017,7 @@ unsigned long approxidate_careful(const char *date, int *error_ret) if (!error_ret) error_ret = &dummy; - if (parse_date_toffset(date, ×tamp, &offset) > 0) { + if (!parse_date_basic(date, ×tamp, &offset)) { *error_ret = 0; return timestamp; } @@ -2704,10 +2704,16 @@ static void diff_fill_sha1_info(struct diff_filespec *one) static void strip_prefix(int prefix_length, const char **namep, const char **otherp) { /* Strip the prefix but do not molest /dev/null and absolute paths */ - if (*namep && **namep != '/') + if (*namep && **namep != '/') { *namep += prefix_length; - if (*otherp && **otherp != '/') + if (**namep == '/') + ++*namep; + } + if (*otherp && **otherp != '/') { *otherp += prefix_length; + if (**otherp == '/') + ++*otherp; + } } static void run_diff(struct diff_filepair *p, struct diff_options *o) @@ -2814,7 +2820,6 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) void diff_setup(struct diff_options *options) { memset(options, 0, sizeof(*options)); - memset(&diff_queued_diff, 0, sizeof(diff_queued_diff)); options->file = stdout; diff --git a/diffcore.h b/diffcore.h index 491bea0b4..05ebc115a 100644 --- a/diffcore.h +++ b/diffcore.h @@ -18,7 +18,7 @@ #define MAX_SCORE 60000.0 #define DEFAULT_RENAME_SCORE 30000 /* rename/copy similarity minimum (50%) */ #define DEFAULT_BREAK_SCORE 30000 /* minimum for break to happen (50%) */ -#define DEFAULT_MERGE_SCORE 36000 /* maximum for break-merge to happen 60%) */ +#define DEFAULT_MERGE_SCORE 36000 /* maximum for break-merge to happen (60%) */ #define MINIMUM_BREAK_SIZE 400 /* do not break a file smaller than this */ @@ -98,7 +98,7 @@ struct diff_queue_struct { (q)->queue = NULL; \ (q)->nr = (q)->alloc = 0; \ (q)->run = 0; \ - } while(0); + } while (0) extern struct diff_queue_struct diff_queued_diff; extern struct diff_filepair *diff_queue(struct diff_queue_struct *, @@ -118,9 +118,9 @@ void diff_debug_filespec(struct diff_filespec *, int, const char *); void diff_debug_filepair(const struct diff_filepair *, int); void diff_debug_queue(const char *, struct diff_queue_struct *); #else -#define diff_debug_filespec(a,b,c) do {} while(0) -#define diff_debug_filepair(a,b) do {} while(0) -#define diff_debug_queue(a,b) do {} while(0) +#define diff_debug_filespec(a,b,c) do { /* nothing */ } while (0) +#define diff_debug_filepair(a,b) do { /* nothing */ } while (0) +#define diff_debug_queue(a,b) do { /* nothing */ } while (0) #endif extern int diffcore_count_changes(struct diff_filespec *src, diff --git a/fast-import.c b/fast-import.c index 1e5d66ed0..ddad289da 100644 --- a/fast-import.c +++ b/fast-import.c @@ -1666,7 +1666,7 @@ static void dump_marks_helper(FILE *f, if (m->shift) { for (k = 0; k < 1024; k++) { if (m->data.sets[k]) - dump_marks_helper(f, (base + k) << m->shift, + dump_marks_helper(f, base + (k << m->shift), m->data.sets[k]); } } else { diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 7d5451198..bb104895a 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -38,7 +38,7 @@ if {[catch {package require Tcl 8.4} err] tk_messageBox \ -icon error \ -type ok \ - -title [mc "git-gui: fatal error"] \ + -title "git-gui: fatal error" \ -message $err exit 1 } @@ -269,6 +269,17 @@ proc is_config_true {name} { } } +proc is_config_false {name} { + global repo_config + if {[catch {set v $repo_config($name)}]} { + return 0 + } elseif {$v eq {false} || $v eq {0} || $v eq {no}} { + return 1 + } else { + return 0 + } +} + proc get_config {name} { global repo_config if {[catch {set v $repo_config($name)}]} { @@ -323,6 +334,8 @@ proc _trace_exec {cmd} { puts stderr $d } +#'" fix poor old emacs font-lock mode + proc _git_cmd {name} { global _git_cmd_path @@ -416,6 +429,9 @@ proc _lappend_nice {cmd_var} { if {![info exists _nice]} { set _nice [_which nice] + if {[catch {exec $_nice git version}]} { + set _nice {} + } } if {$_nice ne {}} { lappend cmd $_nice @@ -634,6 +650,7 @@ proc rmsel_tag {text} { return $text } +wm withdraw . set root_exists 0 bind . <Visibility> { bind . <Visibility> {} @@ -782,6 +799,7 @@ set default_config(user.email) {} set default_config(gui.encoding) [encoding system] set default_config(gui.matchtrackingbranch) false +set default_config(gui.textconv) true set default_config(gui.pruneduringfetch) false set default_config(gui.trustmtime) false set default_config(gui.fastcopyblame) false @@ -1155,6 +1173,9 @@ apply_config # try to set work tree from environment, falling back to core.worktree if {[catch { set _gitworktree $env(GIT_WORK_TREE) }]} { set _gitworktree [get_config core.worktree] + if {$_gitworktree eq ""} { + set _gitworktree [file dirname [file normalize $_gitdir]] + } } if {$_prefix ne {}} { if {$_gitworktree eq {}} { @@ -2098,7 +2119,7 @@ proc do_explore {} { # freedesktop.org-conforming system is our best shot set explorer "xdg-open" } - eval exec $explorer $_gitworktree & + eval exec $explorer [list [file nativename $_gitworktree]] & } set is_quitting 0 @@ -2901,6 +2922,7 @@ blame { set current_branch $head } + wm deiconify . switch -- $subcommand { browser { if {$jump_spec ne {}} usage @@ -3405,6 +3427,19 @@ lappend diff_actions [list $ctxmsm entryconf [$ctxmsm index last] -state] $ctxmsm add separator create_common_diff_popup $ctxmsm +proc has_textconv {path} { + if {[is_config_false gui.textconv]} { + return 0 + } + set filter [gitattr $path diff set] + set textconv [get_config [join [list diff $filter textconv] .]] + if {$filter ne {set} && $textconv ne {}} { + return 1 + } else { + return 0 + } +} + proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} { global current_diff_path file_states set ::cursorX $x @@ -3440,7 +3475,8 @@ proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} { || {__} eq $state || {_O} eq $state || {_T} eq $state - || {T_} eq $state} { + || {T_} eq $state + || [has_textconv $current_diff_path]} { set s disabled } else { set s normal @@ -3460,29 +3496,44 @@ $main_status show [mc "Initializing..."] # -- Load geometry # -catch { -set gm $repo_config(gui.geometry) -wm geometry . [lindex $gm 0] -if {$use_ttk} { - .vpane sashpos 0 [lindex $gm 1] - .vpane.files sashpos 0 [lindex $gm 2] -} else { - .vpane sash place 0 \ - [lindex $gm 1] \ - [lindex [.vpane sash coord 0] 1] - .vpane.files sash place 0 \ - [lindex [.vpane.files sash coord 0] 0] \ - [lindex $gm 2] +proc on_ttk_pane_mapped {w pane pos} { + bind $w <Map> {} + after 0 [list after idle [list $w sashpos $pane $pos]] +} +proc on_tk_pane_mapped {w pane x y} { + bind $w <Map> {} + after 0 [list after idle [list $w sash place $pane $x $y]] +} +proc on_application_mapped {} { + global repo_config use_ttk + bind . <Map> {} + set gm $repo_config(gui.geometry) + if {$use_ttk} { + bind .vpane <Map> \ + [list on_ttk_pane_mapped %W 0 [lindex $gm 1]] + bind .vpane.files <Map> \ + [list on_ttk_pane_mapped %W 0 [lindex $gm 2]] + } else { + bind .vpane <Map> \ + [list on_tk_pane_mapped %W 0 \ + [lindex $gm 1] \ + [lindex [.vpane sash coord 0] 1]] + bind .vpane.files <Map> \ + [list on_tk_pane_mapped %W 0 \ + [lindex [.vpane.files sash coord 0] 0] \ + [lindex $gm 2]] + } + wm geometry . [lindex $gm 0] } -unset gm +if {[info exists repo_config(gui.geometry)]} { + bind . <Map> [list on_application_mapped] + wm geometry . [lindex $repo_config(gui.geometry) 0] } # -- Load window state # -catch { -set gws $repo_config(gui.wmstate) -wm state . $gws -unset gws +if {[info exists repo_config(gui.wmstate)]} { + catch {wm state . $repo_config(gui.wmstate)} } # -- Key Bindings diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 786b50b8c..2137ec968 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -449,11 +449,28 @@ method _load {jump} { $status show [mc "Reading %s..." "$commit:[escape_path $path]"] $w_path conf -text [escape_path $path] + + set do_textconv 0 + if {![is_config_false gui.textconv] && [git-version >= 1.7.2]} { + set filter [gitattr $path diff set] + set textconv [get_config [join [list diff $filter textconv] .]] + if {$filter ne {set} && $textconv ne {}} { + set do_textconv 1 + } + } if {$commit eq {}} { - set fd [open $path r] + if {$do_textconv ne 0} { + set fd [open |[list $textconv $path] r] + } else { + set fd [open $path r] + } fconfigure $fd -eofchar {} } else { - set fd [git_read cat-file blob "$commit:$path"] + if {$do_textconv ne 0} { + set fd [git_read cat-file --textconv "$commit:$path"] + } else { + set fd [git_read cat-file blob "$commit:$path"] + } } fconfigure $fd \ -blocking 0 \ diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl index 64f06748b..fae119286 100644 --- a/git-gui/lib/choose_repository.tcl +++ b/git-gui/lib/choose_repository.tcl @@ -100,12 +100,17 @@ constructor pick {} { $opts insert end [mc "Clone Existing Repository"] link_clone $opts insert end "\n" if {$m_repo ne {}} { + if {[tk windowingsystem] eq "win32"} { + set key L + } else { + set key C + } $m_repo add command \ -command [cb _next clone] \ - -accelerator $M1T-C \ + -accelerator $M1T-$key \ -label [mc "Clone..."] - bind $top <$M1B-c> [cb _next clone] - bind $top <$M1B-C> [cb _next clone] + bind $top <$M1B-[string tolower $key]> [cb _next clone] + bind $top <$M1B-[string toupper $key]> [cb _next clone] } $opts tag conf link_open -foreground blue -underline 1 diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index ec8c11eeb..c62875027 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -55,7 +55,7 @@ proc handle_empty_diff {} { set path $current_diff_path set s $file_states($path) - if {[lindex $s 0] ne {_M}} return + if {[lindex $s 0] ne {_M} || [has_textconv $path]} return # Prevent infinite rescan loops incr diff_empty_count @@ -280,6 +280,9 @@ proc start_show_diff {cont_info {add_opts {}}} { lappend cmd diff-files } } + if {![is_config_false gui.textconv] && [git-version >= 1.6.1]} { + lappend cmd --textconv + } if {[string match {160000 *} [lindex $s 2]] || [string match {160000 *} [lindex $s 3]]} { diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl index d4c5e45c8..3807c8d28 100644 --- a/git-gui/lib/option.tcl +++ b/git-gui/lib/option.tcl @@ -148,6 +148,7 @@ proc do_options {} { {b gui.trustmtime {mc "Trust File Modification Timestamps"}} {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}} {b gui.matchtrackingbranch {mc "Match Tracking Branches"}} + {b gui.textconv {mc "Use Textconv For Diffs and Blames"}} {b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}} {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}} {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}} diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 79c1888e1..78878ef89 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -16,7 +16,7 @@ proc do_windows_shortcut {} { [info nameofexecutable] \ [file normalize $::argv0] \ ] \ - [file normalize [$_gitworktree]] + [file normalize $_gitworktree] } err]} { error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] } @@ -57,7 +57,7 @@ proc do_cygwin_shortcut {} { $sh -c \ "CHERE_INVOKING=1 source /etc/profile;[sq $me] &" \ ] \ - [file normalize [$_gitworktree]] + [file normalize $_gitworktree] } err]} { error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] } diff --git a/git-gui/lib/status_bar.tcl b/git-gui/lib/status_bar.tcl index 5fe3aad38..95cb44991 100644 --- a/git-gui/lib/status_bar.tcl +++ b/git-gui/lib/status_bar.tcl @@ -39,6 +39,7 @@ method _oneline_pack {} { } constructor two_line {path} { + global NS set w $path set w_l $w.l set w_c $w.c diff --git a/git-gui/lib/win32.tcl b/git-gui/lib/win32.tcl index d7f93d045..db91ab84a 100644 --- a/git-gui/lib/win32.tcl +++ b/git-gui/lib/win32.tcl @@ -18,9 +18,9 @@ proc win32_create_lnk {lnk_path lnk_exec lnk_dir} { eval [list exec wscript.exe \ /E:jscript \ /nologo \ - [file join $oguilib win32_shortcut.js] \ + [file nativename [file join $oguilib win32_shortcut.js]] \ $lnk_path \ - [file join $oguilib git-gui.ico] \ + [file nativename [file join $oguilib git-gui.ico]] \ $lnk_dir \ $lnk_exec] $lnk_args } diff --git a/git-gui/windows/git-gui.sh b/git-gui/windows/git-gui.sh index 66bbb2f8f..b1845c505 100644 --- a/git-gui/windows/git-gui.sh +++ b/git-gui/windows/git-gui.sh @@ -13,10 +13,11 @@ if { $argc >=2 && [lindex $argv 0] == "--working-dir" } { incr argc -2 } -set bindir [file dirname \ +set basedir [file dirname \ [file dirname \ [file dirname [info script]]]] -set bindir [file join $bindir bin] +set bindir [file join $basedir bin] +set bindir "$bindir;[file join $basedir mingw bin]" regsub -all ";" $bindir "\\;" bindir set env(PATH) "$bindir;$env(PATH)" unset bindir diff --git a/git-instaweb.sh b/git-instaweb.sh index 6635fbefd..e6f6ecda1 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -43,7 +43,8 @@ test -z "$port" && port=1234 resolve_full_httpd () { case "$httpd" in - *apache2*|*lighttpd*) + *apache2*|*lighttpd*|*httpd*) + # yes, *httpd* covers *lighttpd* above, but it is there for clarity # ensure that the apache2/lighttpd command ends with "-f" if ! echo "$httpd" | sane_grep -- '-f *$' >/dev/null 2>&1 then @@ -56,6 +57,13 @@ resolve_full_httpd () { httpd_only="${httpd%% *}" # cut on first space return ;; + *webrick*) + # server is started by running via generated webrick.rb in + # $fqgitdir/gitweb + full_httpd="$fqgitdir/gitweb/webrick.rb" + httpd_only="${httpd%% *}" # cut on first space + return + ;; esac httpd_only="$(echo $httpd | cut -f1 -d' ')" @@ -187,40 +195,53 @@ GITWEB_CONFIG="$fqgitdir/gitweb/gitweb_config.perl" export GIT_EXEC_PATH GIT_DIR GITWEB_CONFIG webrick_conf () { + # webrick seems to have no way of passing arbitrary environment + # variables to the underlying CGI executable, so we wrap the + # actual gitweb.cgi using a shell script to force it + wrapper="$fqgitdir/gitweb/$httpd/wrapper.sh" + cat > "$wrapper" <<EOF +#!/bin/sh +# we use this shell script wrapper around the real gitweb.cgi since +# there appears to be no other way to pass arbitrary environment variables +# into the CGI process +GIT_EXEC_PATH=$GIT_EXEC_PATH GIT_DIR=$GIT_DIR GITWEB_CONFIG=$GITWEB_CONFIG +export GIT_EXEC_PATH GIT_DIR GITWEB_CONFIG +exec $root/gitweb.cgi +EOF + chmod +x "$wrapper" + + # This assumes _ruby_ is in the user's $PATH. that's _one_ + # portable way to run ruby, which could be installed anywhere, really. # generate a standalone server script in $fqgitdir/gitweb. cat >"$fqgitdir/gitweb/$httpd.rb" <<EOF +#!/usr/bin/env ruby require 'webrick' -require 'yaml' -options = YAML::load_file(ARGV[0]) -options[:StartCallback] = proc do - File.open(options[:PidFile],"w") do |f| - f.puts Process.pid - end -end -options[:ServerType] = WEBrick::Daemon +require 'logger' +options = { + :Port => $port, + :DocumentRoot => "$root", + :Logger => Logger.new('$fqgitdir/gitweb/error.log'), + :AccessLog => [ + [ Logger.new('$fqgitdir/gitweb/access.log'), + WEBrick::AccessLog::COMBINED_LOG_FORMAT ] + ], + :DirectoryIndex => ["gitweb.cgi"], + :CGIInterpreter => "$wrapper", + :StartCallback => lambda do + File.open("$fqgitdir/pid", "w") { |f| f.puts Process.pid } + end, + :ServerType => WEBrick::Daemon, +} +options[:BindAddress] = '127.0.0.1' if "$local" == "true" server = WEBrick::HTTPServer.new(options) ['INT', 'TERM'].each do |signal| trap(signal) {server.shutdown} end server.start EOF - # generate a shell script to invoke the above ruby script, - # which assumes _ruby_ is in the user's $PATH. that's _one_ - # portable way to run ruby, which could be installed anywhere, - # really. - cat >"$fqgitdir/gitweb/$httpd" <<EOF -#!/bin/sh -exec ruby "$fqgitdir/gitweb/$httpd.rb" \$* -EOF - chmod +x "$fqgitdir/gitweb/$httpd" - - cat >"$conf" <<EOF -:Port: $port -:DocumentRoot: "$root" -:DirectoryIndex: ["gitweb.cgi"] -:PidFile: "$fqgitdir/pid" -EOF - test "$local" = true && echo ':BindAddress: "127.0.0.1"' >> "$conf" + chmod +x "$fqgitdir/gitweb/$httpd.rb" + # configuration is embedded in server script file, webrick.rb + rm -f "$conf" } lighttpd_conf () { @@ -300,7 +321,13 @@ EOF } apache2_conf () { - test -z "$module_path" && module_path=/usr/lib/apache2/modules + if test -z "$module_path" + then + test -d "/usr/lib/httpd/modules" && + module_path="/usr/lib/httpd/modules" + test -d "/usr/lib/apache2/modules" && + module_path="/usr/lib/apache2/modules" + fi bind= test x"$local" = xtrue && bind='127.0.0.1:' echo 'text/css css' > "$fqgitdir/mime.types" @@ -314,8 +341,10 @@ PidFile "$fqgitdir/pid" Listen $bind$port EOF - for mod in mime dir; do - if test -e $module_path/mod_${mod}.so; then + for mod in mime dir env log_config + do + if test -e $module_path/mod_${mod}.so + then echo "LoadModule ${mod}_module " \ "$module_path/mod_${mod}.so" >> "$conf" fi @@ -334,7 +363,7 @@ EOF cat >> "$conf" <<EOF LoadModule perl_module $module_path/mod_perl.so PerlPassEnv GIT_DIR -PerlPassEnv GIT_EXEC_DIR +PerlPassEnv GIT_EXEC_PATH PerlPassEnv GITWEB_CONFIG <Location /gitweb.cgi> SetHandler perl-script @@ -364,6 +393,9 @@ EOF echo "ScriptSock logs/gitweb.sock" >> "$conf" fi cat >> "$conf" <<EOF +PassEnv GIT_DIR +PassEnv GIT_EXEC_PATH +PassEnv GITWEB_CONFIG AddHandler cgi-script .cgi <Location /gitweb.cgi> Options +ExecCGI @@ -560,7 +592,7 @@ case "$httpd" in *lighttpd*) lighttpd_conf ;; -*apache2*) +*apache2*|*httpd*) apache2_conf ;; webrick) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 31e68603f..b94c2a038 100755 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -119,7 +119,7 @@ run 'git rebase --continue'" export GIT_CHERRY_PICK_HELP warn () { - echo "$*" >&2 + printf '%s\n' "$*" >&2 } output () { @@ -606,7 +606,7 @@ skip_unnecessary_picks () { fd=1 ;; esac - echo "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd + printf '%s\n' "$command${sha1:+ }$sha1${rest:+ }$rest" >&$fd done <"$TODO" >"$TODO.new" 3>>"$DONE" && mv -f "$TODO".new "$TODO" && case "$(peek_next_command)" in @@ -649,12 +649,12 @@ rearrange_squash () { case " $used" in *" $sha1 "*) continue ;; esac - echo "$pick $sha1 $message" + printf '%s\n' "$pick $sha1 $message" while read -r squash action msg do case "$message" in "$msg"*) - echo "$action $squash $action! $msg" + printf '%s\n' "$action $squash $action! $msg" used="$used$squash " ;; esac @@ -895,7 +895,7 @@ first and then run 'git rebase --continue' again." do if test t != "$PRESERVE_MERGES" then - echo "pick $shortsha1 $rest" >> "$TODO" + printf '%s\n' "pick $shortsha1 $rest" >> "$TODO" else sha1=$(git rev-parse $shortsha1) if test -z "$REBASE_ROOT" @@ -914,7 +914,7 @@ first and then run 'git rebase --continue' again." if test f = "$preserve" then touch "$REWRITTEN"/$sha1 - echo "pick $shortsha1 $rest" >> "$TODO" + printf '%s\n' "pick $shortsha1 $rest" >> "$TODO" fi fi done diff --git a/git-rebase.sh b/git-rebase.sh index ab4afa7de..1d38afdb1 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -208,6 +208,7 @@ do test -d "$dotest" -o -d "$GIT_DIR"/rebase-apply || die "No rebase in progress?" + git update-index --ignore-submodules --refresh && git diff-files --quiet --ignore-submodules || { echo "You must edit all merge conflicts and then" echo "mark them as resolved using git add" @@ -345,7 +346,7 @@ do --root) rebase_root=t ;; - -f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase|--no-ff) + -f|--f|--fo|--for|--forc|--force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase|--no-ff) force_rebase=t ;; --rerere-autoupdate|--no-rerere-autoupdate) diff --git a/git-svn.perl b/git-svn.perl index c4163584a..34884b8fc 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -494,6 +494,7 @@ sub cmd_set_tree { sub cmd_dcommit { my $head = shift; + command_noisy(qw/update-index --refresh/); git_cmd_try { command_oneline(qw/diff-index --quiet HEAD/) } 'Cannot dcommit with a dirty index. Commit your changes first, ' . "or stash them with `git stash'.\n"; @@ -1819,6 +1820,7 @@ sub read_all_remotes { die("svn-remote.$remote: remote ref '$remote_ref' " . "must start with 'refs/'\n") unless $remote_ref =~ m{^refs/}; + $local_ref = uri_decode($local_ref); $r->{$remote}->{fetch}->{$local_ref} = $remote_ref; $r->{$remote}->{svm} = {} if $use_svm_props; } elsif (m!^(.+)\.usesvmprops=\s*(.*)\s*$!) { @@ -1831,6 +1833,7 @@ sub read_all_remotes { die("svn-remote.$remote: remote ref '$remote_ref' ($t) " . "must start with 'refs/'\n") unless $remote_ref =~ m{^refs/}; + $local_ref = uri_decode($local_ref); my $rs = { t => $t, remote => $remote, @@ -4050,6 +4053,7 @@ sub new { $self->{absent_dir} = {}; $self->{absent_file} = {}; $self->{gii} = $git_svn->tmp_index_do(sub { Git::IndexInfo->new }); + $self->{pathnameencoding} = Git::config('svn.pathnameencoding'); $self; } @@ -4133,6 +4137,10 @@ sub open_directory { sub git_path { my ($self, $path) = @_; + if (my $enc = $self->{pathnameencoding}) { + require Encode; + Encode::from_to($path, 'UTF-8', $enc); + } if ($self->{path_strip}) { $path =~ s!$self->{path_strip}!! or die "Failed to strip path '$path' ($self->{path_strip})\n"; @@ -4521,6 +4529,10 @@ sub split_path { sub repo_path { my ($self, $path) = @_; + if (my $enc = $self->{pathnameencoding}) { + require Encode; + Encode::from_to($path, $enc, 'UTF-8'); + } $self->{path_prefix}.(defined $path ? $path : ''); } diff --git a/git-web--browse.sh b/git-web--browse.sh index dbded76aa..3fc4166b2 100755 --- a/git-web--browse.sh +++ b/git-web--browse.sh @@ -31,7 +31,7 @@ valid_custom_tool() valid_tool() { case "$1" in - firefox | iceweasel | chrome | chromium | konqueror | w3m | links | lynx | dillo | open | start) + firefox | iceweasel | chrome | google-chrome | chromium | konqueror | w3m | links | lynx | dillo | open | start) ;; # happy *) valid_custom_tool "$1" || return 1 @@ -103,7 +103,7 @@ fi if test -z "$browser" ; then if test -n "$DISPLAY"; then - browser_candidates="firefox iceweasel chrome chromium konqueror w3m links lynx dillo" + browser_candidates="firefox iceweasel google-chrome chrome chromium konqueror w3m links lynx dillo" if test "$KDE_FULL_SESSION" = "true"; then browser_candidates="konqueror $browser_candidates" fi @@ -146,7 +146,7 @@ case "$browser" in test "$vers" -lt 2 && NEWTAB='' "$browser_path" $NEWTAB "$@" & ;; - chrome|chromium) + google-chrome|chrome|chromium) # Actual command for chromium is chromium-browser. # No need to specify newTab. It's default in chromium eval "$browser_path" "$@" & @@ -8,8 +8,8 @@ const char git_usage_string[] = "git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]\n" " [-p|--paginate|--no-pager] [--no-replace-objects]\n" " [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]\n" - " [-c name=value\n" - " [--help] COMMAND [ARGS]"; + " [-c name=value] [--help]\n" + " COMMAND [ARGS]"; const char git_more_info_string[] = "See 'git help COMMAND' for more information on a specific command."; diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index c1e910af6..898b121b5 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -232,6 +232,29 @@ our %avatar_size = ( # Leave it undefined (or set to 'undef') to turn off load checking. our $maxload = 300; +# configuration for 'highlight' (http://www.andre-simon.de/) +# match by basename +our %highlight_basename = ( + #'Program' => 'py', + #'Library' => 'py', + 'SConstruct' => 'py', # SCons equivalent of Makefile + 'Makefile' => 'make', +); +# match by extension +our %highlight_ext = ( + # main extensions, defining name of syntax; + # see files in /usr/share/highlight/langDefs/ directory + map { $_ => $_ } + qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl), + # alternate extensions, see /etc/highlight/filetypes.conf + 'h' => 'c', + map { $_ => 'cpp' } qw(cxx c++ cc), + map { $_ => 'php' } qw(php3 php4), + map { $_ => 'pl' } qw(perl pm), # perhaps also 'cgi' + 'mak' => 'make', + map { $_ => 'xml' } qw(xhtml html htm), +); + # You define site-wide feature defaults here; override them with # $GITWEB_CONFIG as necessary. our %feature = ( @@ -1102,7 +1125,7 @@ sub run { run_request(); - $pre_dispatch_hook->() + $post_dispatch_hook->() if $post_dispatch_hook; last REQUEST if ($is_last_request->()); @@ -3316,30 +3339,6 @@ sub blob_contenttype { sub guess_file_syntax { my ($highlight, $mimetype, $file_name) = @_; return undef unless ($highlight && defined $file_name); - - # configuration for 'highlight' (http://www.andre-simon.de/) - # match by basename - my %highlight_basename = ( - #'Program' => 'py', - #'Library' => 'py', - 'SConstruct' => 'py', # SCons equivalent of Makefile - 'Makefile' => 'make', - ); - # match by extension - my %highlight_ext = ( - # main extensions, defining name of syntax; - # see files in /usr/share/highlight/langDefs/ directory - map { $_ => $_ } - qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl), - # alternate extensions, see /etc/highlight/filetypes.conf - 'h' => 'c', - map { $_ => 'cpp' } qw(cxx c++ cc), - map { $_ => 'php' } qw(php3 php4), - map { $_ => 'pl' } qw(perl pm), # perhaps also 'cgi' - 'mak' => 'make', - map { $_ => 'xml' } qw(xhtml html htm), - ); - my $basename = basename($file_name, '.in'); return $highlight_basename{$basename} if exists $highlight_basename{$basename}; @@ -6522,12 +6521,13 @@ sub git_search { $paging_nav .= " ⋅ next"; } - if ($#commitlist >= 100) { - } - git_print_page_nav('','', $hash,$co{'tree'},$hash, $paging_nav); git_print_header_div('commit', esc_html($co{'title'}), $hash); - git_search_grep_body(\@commitlist, 0, 99, $next_link); + if ($page == 0 && !@commitlist) { + print "<p>No match.</p>\n"; + } else { + git_search_grep_body(\@commitlist, 0, 99, $next_link); + } } if ($searchtype eq 'pickaxe') { @@ -23,10 +23,10 @@ #endif #if LIBCURL_VERSION_NUM < 0x070704 -#define curl_global_cleanup() do { /* nothing */ } while(0) +#define curl_global_cleanup() do { /* nothing */ } while (0) #endif #if LIBCURL_VERSION_NUM < 0x070800 -#define curl_global_init(a) do { /* nothing */ } while(0) +#define curl_global_init(a) do { /* nothing */ } while (0) #endif #if (LIBCURL_VERSION_NUM < 0x070c04) || (LIBCURL_VERSION_NUM == 0x071000) diff --git a/imap-send.c b/imap-send.c index 1a577a0a0..71506a8dd 100644 --- a/imap-send.c +++ b/imap-send.c @@ -543,9 +543,13 @@ static struct imap_cmd *v_issue_imap_cmd(struct imap_store *ctx, while (imap->literal_pending) get_cmd_result(ctx, NULL); - bufl = nfsnprintf(buf, sizeof(buf), cmd->cb.data ? CAP(LITERALPLUS) ? - "%d %s{%d+}\r\n" : "%d %s{%d}\r\n" : "%d %s\r\n", - cmd->tag, cmd->cmd, cmd->cb.dlen); + if (!cmd->cb.data) + bufl = nfsnprintf(buf, sizeof(buf), "%d %s\r\n", cmd->tag, cmd->cmd); + else + bufl = nfsnprintf(buf, sizeof(buf), "%d %s{%d%s}\r\n", + cmd->tag, cmd->cmd, cmd->cb.dlen, + CAP(LITERALPLUS) ? "+" : ""); + if (Verbose) { if (imap->num_in_progress) printf("(%d in progress) ", imap->num_in_progress); @@ -1086,7 +1090,7 @@ static struct store *imap_open_store(struct imap_server_conf *srvc) int gai; char portstr[6]; - snprintf(portstr, sizeof(portstr), "%hu", srvc->port); + snprintf(portstr, sizeof(portstr), "%d", srvc->port); memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; diff --git a/pack-refs.c b/pack-refs.c index 7f43f8ac3..129057026 100644 --- a/pack-refs.c +++ b/pack-refs.c @@ -60,6 +60,37 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, return 0; } +/* + * Remove empty parents, but spare refs/ and immediate subdirs. + * Note: munges *name. + */ +static void try_remove_empty_parents(char *name) +{ + char *p, *q; + int i; + p = name; + for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */ + while (*p && *p != '/') + p++; + /* tolerate duplicate slashes; see check_ref_format() */ + while (*p == '/') + p++; + } + for (q = p; *q; q++) + ; + while (1) { + while (q > p && *q != '/') + q--; + while (q > p && *(q-1) == '/') + q--; + if (q == p) + break; + *q = '\0'; + if (rmdir(git_path("%s", name))) + break; + } +} + /* make sure nobody touched the ref, and unlink */ static void prune_ref(struct ref_to_prune *r) { @@ -68,6 +99,7 @@ static void prune_ref(struct ref_to_prune *r) if (lock) { unlink_or_warn(git_path("%s", r->name)); unlock_ref(lock); + try_remove_empty_parents(r->name); } } @@ -316,6 +316,8 @@ char *expand_user_path(const char *path) size_t username_len = first_slash - username; if (username_len == 0) { const char *home = getenv("HOME"); + if (!home) + goto return_null; strbuf_add(&user_path, home, strlen(home)); } else { struct passwd *pw = getpw_str(username, username_len); diff --git a/remote-curl.c b/remote-curl.c index 24fbb9a9b..04d4813e4 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -528,11 +528,12 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) rpc->len = n; err |= post_rpc(rpc); } - strbuf_read(&rpc->result, client.out, 0); close(client.in); - close(client.out); client.in = -1; + strbuf_read(&rpc->result, client.out, 0); + + close(client.out); client.out = -1; err |= finish_command(&client); diff --git a/t/.gitignore b/t/.gitignore index 7dcbb232c..4e731dc1e 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -1,2 +1,3 @@ /trash directory* /test-results +/.prove diff --git a/t/Makefile b/t/Makefile index cf5f9e2e1..819b93687 100644 --- a/t/Makefile +++ b/t/Makefile @@ -30,6 +30,7 @@ clean: $(RM) -r 'trash directory'.* test-results $(RM) t????/cvsroot/CVSROOT/?* $(RM) -r valgrind/bin + $(RM) .prove aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index c3f6676ca..92d6d3194 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -16,7 +16,6 @@ fi GIT_DIR=$PWD/.git GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn SVN_TREE=$GIT_SVN_DIR/svn-tree -PERL=${PERL:-perl} svn >/dev/null 2>&1 if test $? -ne 1 @@ -30,7 +29,7 @@ export svnrepo svnconf=$PWD/svnconf export svnconf -$PERL -w -e " +"$PERL_PATH" -w -e " use SVN::Core; use SVN::Repos; \$SVN::Core::VERSION gt '1.1.0' or exit(42); @@ -130,7 +129,7 @@ stop_httpd () { } convert_to_rev_db () { - $PERL -w -- - "$@" <<\EOF + "$PERL_PATH" -w -- - "$@" <<\EOF use strict; @ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>"; open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]"; diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 64f05080b..074f2f2e3 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -707,19 +707,41 @@ test_expect_success 'set --path' ' git config --path path.trailingtilde "foo~" && test_cmp expect .git/config' +if test "${HOME+set}" +then + test_set_prereq HOMEVAR +fi + cat >expect <<EOF $HOME/ /dev/null foo~ EOF -test_expect_success 'get --path' ' +test_expect_success HOMEVAR 'get --path' ' git config --get --path path.home > result && git config --get --path path.normal >> result && git config --get --path path.trailingtilde >> result && test_cmp expect result ' +cat >expect <<\EOF +/dev/null +foo~ +EOF + +test_expect_success 'get --path copes with unset $HOME' ' + ( + unset HOME; + test_must_fail git config --get --path path.home \ + >result 2>msg && + git config --get --path path.normal >>result && + git config --get --path path.trailingtilde >>result + ) && + grep "[Ff]ailed to expand.*~/" msg && + test_cmp expect result +' + rm .git/config git config quote.leading " test" diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index eb45afb01..782e75d00 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -41,6 +41,23 @@ test_expect_success "check-ref-format --branch @{-1}" ' refname2=$(git check-ref-format --branch @{-2}) && test "$refname2" = master' +test_expect_success 'check-ref-format --branch from subdir' ' + mkdir subdir && + + T=$(git write-tree) && + sha1=$(echo A | git commit-tree $T) && + git update-ref refs/heads/master $sha1 && + git update-ref refs/remotes/origin/master $sha1 + git checkout master && + git checkout origin/master && + git checkout master && + refname=$( + cd subdir && + git check-ref-format --branch @{-1} + ) && + test "$refname" = "$sha1" +' + valid_ref_normalized() { test_expect_success "ref name '$1' simplifies to '$2'" " refname=\$(git check-ref-format --print '$1') && diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 525174013..cd04361df 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -60,6 +60,12 @@ test_expect_success 'see if git pack-refs --prune remove ref files' ' ! test -f .git/refs/heads/f ' +test_expect_success 'see if git pack-refs --prune removes empty dirs' ' + git branch r/s/t && + git pack-refs --all --prune && + ! test -e .git/refs/heads/r +' + test_expect_success \ 'git branch g should work when git branch g/h has been deleted' \ 'git branch g/h && diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 47ca88fc5..9f03ce699 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -637,13 +637,19 @@ test_expect_success 'set up commits with funny messages' ' git commit -a -m "end with slash\\" && echo >>file1 && test_tick && + git commit -a -m "something (\000) that looks like octal" && + echo >>file1 && + test_tick && + git commit -a -m "something (\n) that looks like a newline" && + echo >>file1 && + test_tick && git commit -a -m "another commit" ' test_expect_success 'rebase-i history with funny messages' ' git rev-list A..funny >expect && test_tick && - FAKE_LINES="1 2" git rebase -i A && + FAKE_LINES="1 2 3 4" git rebase -i A && git rev-list A.. >actual && test_cmp expect actual ' diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh new file mode 100755 index 000000000..3b0d27350 --- /dev/null +++ b/t/t3418-rebase-continue.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +test_description='git rebase --continue tests' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-rebase.sh + +set_fake_editor + +test_expect_success 'setup' ' + test_commit "commit-new-file-F1" F1 1 && + test_commit "commit-new-file-F2" F2 2 && + + git checkout -b topic HEAD^ && + test_commit "commit-new-file-F2-on-topic-branch" F2 22 && + + git checkout master +' + +test_expect_success 'interactive rebase --continue works with touched file' ' + rm -fr .git/rebase-* && + git reset --hard && + git checkout master && + + FAKE_LINES="edit 1" git rebase -i HEAD^ && + test-chmtime =-60 F1 && + git rebase --continue +' + +test_expect_success 'non-interactive rebase --continue works with touched file' ' + rm -fr .git/rebase-* && + git reset --hard && + git checkout master && + + test_must_fail git rebase --onto master master topic && + echo "Resolved" >F2 && + git add F2 && + test-chmtime =-60 F1 && + git rebase --continue +' + +test_done diff --git a/t/t3700-add.sh b/t/t3700-add.sh index d03495dc7..7d7140db3 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -272,17 +272,20 @@ test_expect_success 'git add --dry-run of non-existing file' " echo \"fatal: pathspec 'ignored-file' did not match any files\" | test_cmp - actual " -cat >expect <<EOF +cat >expect.err <<\EOF The following paths are ignored by one of your .gitignore files: ignored-file Use -f if you really want to add them. fatal: no files added +EOF +cat >expect.out <<\EOF add 'track-this' EOF test_expect_success 'git add --dry-run --ignore-missing of non-existing file' ' - test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual 2>&1 && - test_cmp expect actual + test_must_fail git add --dry-run --ignore-missing track-this ignored-file >actual.out 2>actual.err && + test_cmp expect.out actual.out && + test_cmp expect.err actual.err ' test_done diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh new file mode 100755 index 000000000..8a3c63b9e --- /dev/null +++ b/t/t4045-diff-relative.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +test_description='diff --relative tests' +. ./test-lib.sh + +test_expect_success 'setup' ' + git commit --allow-empty -m empty && + echo content >file1 && + mkdir subdir && + echo other content >subdir/file2 && + git add . && + git commit -m one +' + +check_diff() { +expect=$1; shift +cat >expected <<EOF +diff --git a/$expect b/$expect +new file mode 100644 +index 0000000..25c05ef +--- /dev/null ++++ b/$expect +@@ -0,0 +1 @@ ++other content +EOF +test_expect_success "-p $*" " + git diff -p $* HEAD^ >actual && + test_cmp expected actual +" +} + +check_stat() { +expect=$1; shift +cat >expected <<EOF + $expect | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) +EOF +test_expect_success "--stat $*" " + git diff --stat $* HEAD^ >actual && + test_cmp expected actual +" +} + +check_raw() { +expect=$1; shift +cat >expected <<EOF +:000000 100644 0000000000000000000000000000000000000000 25c05ef3639d2d270e7fe765a67668f098092bc5 A $expect +EOF +test_expect_success "--raw $*" " + git diff --no-abbrev --raw $* HEAD^ >actual && + test_cmp expected actual +" +} + +for type in diff stat raw; do + check_$type file2 --relative=subdir/ + check_$type file2 --relative=subdir + check_$type dir/file2 --relative=sub +done + +test_done diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 044603c26..6b2a5f4a6 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -60,6 +60,15 @@ test_expect_success 'upload-pack fails due to error in rev-list' ' grep "bad tree object" output.err ' +test_expect_success 'upload-pack error message when bad ref requested' ' + + printf "0045want %s multi_ack_detailed\n00000009done\n0000" \ + "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input && + test_must_fail git upload-pack . <input >output 2>output.err && + grep -q "not our ref" output.err && + ! grep -q multi_ack_detailed output.err +' + test_expect_success 'upload-pack fails due to error in pack-objects enumeration' ' printf "0032want %s\n00000009done\n0000" \ diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 203ffdb17..4185b7ca1 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -219,6 +219,12 @@ test_expect_success 'bisect and replacements' ' git bisect reset ' +test_expect_success 'index-pack and replacements' ' + git --no-replace-objects rev-list --objects HEAD | + git --no-replace-objects pack-objects test- && + git index-pack test-*.pack +' + # # test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 0da13a8d6..2c55801ee 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -143,11 +143,12 @@ test_expect_success 'more setup' ' test_expect_success 'use index-filter to move into a subdirectory' ' git branch directorymoved && git filter-branch -f --index-filter \ - "git ls-files -s | sed \"s-\\t-&newsubdir/-\" | + "git ls-files -s | sed \"s- -&newsubdir/-\" | GIT_INDEX_FILE=\$GIT_INDEX_FILE.new \ git update-index --index-info && mv \"\$GIT_INDEX_FILE.new\" \"\$GIT_INDEX_FILE\"" directorymoved && - test -z "$(git diff HEAD directorymoved:newsubdir)"' + git diff --exit-code HEAD directorymoved:newsubdir +' test_expect_success 'stops when msg filter fails' ' old=$(git rev-parse HEAD) && diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 13766ab16..d5adae640 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -271,6 +271,17 @@ test_expect_success 'able to dcommit to a subdirectory' " test -z \"\`git diff refs/heads/my-bar refs/remotes/bar\`\" " +test_expect_success 'dcommit should not fail with a touched file' ' + test_commit "commit-new-file-foo2" foo2 && + test-chmtime =-60 foo && + git svn dcommit +' + +test_expect_success 'rebase should not fail with a touched file' ' + test-chmtime =-60 foo && + git svn rebase +' + test_expect_success 'able to set-tree to a subdirectory' " echo cba > d && git update-index d && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 131f03298..2aeed7bd0 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -166,6 +166,63 @@ test_expect_success \ test `git rev-parse --verify master:file2` \ = `git rev-parse --verify verify--import-marks:copy-of-file2`' +test_tick +mt=$(git hash-object --stdin < /dev/null) +: >input.blob +: >marks.exp +: >tree.exp + +cat >input.commit <<EOF +commit refs/heads/verify--dump-marks +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +test the sparse array dumping routines with exponentially growing marks +COMMIT +EOF + +i=0 +l=4 +m=6 +n=7 +while test "$i" -lt 27; do + cat >>input.blob <<EOF +blob +mark :$l +data 0 +blob +mark :$m +data 0 +blob +mark :$n +data 0 +EOF + echo "M 100644 :$l l$i" >>input.commit + echo "M 100644 :$m m$i" >>input.commit + echo "M 100644 :$n n$i" >>input.commit + + echo ":$l $mt" >>marks.exp + echo ":$m $mt" >>marks.exp + echo ":$n $mt" >>marks.exp + + printf "100644 blob $mt\tl$i\n" >>tree.exp + printf "100644 blob $mt\tm$i\n" >>tree.exp + printf "100644 blob $mt\tn$i\n" >>tree.exp + + l=$(($l + $l)) + m=$(($m + $m)) + n=$(($l + $n)) + + i=$((1 + $i)) +done + +sort tree.exp > tree.exp_s + +test_expect_success 'A: export marks with large values' ' + cat input.blob input.commit | git fast-import --export-marks=marks.large && + git ls-tree refs/heads/verify--dump-marks >tree.out && + test_cmp tree.exp_s tree.out && + test_cmp marks.exp marks.large' + ### ### series B ### diff --git a/t/test-lib.sh b/t/test-lib.sh index e5523dd69..e8f21d577 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -127,14 +127,13 @@ do -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) verbose=t; shift ;; -q|--q|--qu|--qui|--quie|--quiet) - quiet=t; shift ;; + # Ignore --quiet under a TAP::Harness. Saying how many tests + # passed without the ok/not ok details is always an error. + test -z "$HARNESS_ACTIVE" && quiet=t; shift ;; --with-dashes) with_dashes=t; shift ;; --no-color) color=; shift ;; - --no-python) - # noop now... - shift ;; --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind) valgrind=t; verbose=t; shift ;; --tee) diff --git a/upload-pack.c b/upload-pack.c index dc464d78b..fc79ddef2 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -105,7 +105,7 @@ static void show_edge(struct commit *commit) fprintf(pack_pipe, "-%s\n", sha1_to_hex(commit->object.sha1)); } -static int do_rev_list(int in, int out, void *create_full_pack) +static int do_rev_list(int in, int out, void *user_data) { int i; struct rev_info revs; @@ -118,23 +118,18 @@ static int do_rev_list(int in, int out, void *create_full_pack) if (use_thin_pack) revs.edge_hint = 1; - if (create_full_pack) { - const char *args[] = {"rev-list", "--all", NULL}; - setup_revisions(2, args, &revs, NULL); - } else { - for (i = 0; i < want_obj.nr; i++) { - struct object *o = want_obj.objects[i].item; - /* why??? */ - o->flags &= ~UNINTERESTING; - add_pending_object(&revs, o, NULL); - } - for (i = 0; i < have_obj.nr; i++) { - struct object *o = have_obj.objects[i].item; - o->flags |= UNINTERESTING; - add_pending_object(&revs, o, NULL); - } - setup_revisions(0, NULL, &revs, NULL); + for (i = 0; i < want_obj.nr; i++) { + struct object *o = want_obj.objects[i].item; + /* why??? */ + o->flags &= ~UNINTERESTING; + add_pending_object(&revs, o, NULL); + } + for (i = 0; i < have_obj.nr; i++) { + struct object *o = have_obj.objects[i].item; + o->flags |= UNINTERESTING; + add_pending_object(&revs, o, NULL); } + setup_revisions(0, NULL, &revs, NULL); if (prepare_revision_walk(&revs)) die("revision walk setup failed"); mark_edges_uninteresting(revs.commits, &revs, show_edge); @@ -554,7 +549,8 @@ static void receive_needs(void) */ o = lookup_object(sha1_buf); if (!o || !(o->flags & OUR_REF)) - die("git upload-pack: not our ref %s", line+5); + die("git upload-pack: not our ref %s", + sha1_to_hex(sha1_buf)); if (!(o->flags & WANTED)) { o->flags |= WANTED; add_object_array(o, NULL, &want_obj); |