From: Junio C Hamano Date: Wed, 3 Apr 2013 15:36:10 +0000 (-0700) Subject: Merge branch 'ap/maint-update-index-h-is-for-help' into maint-1.8.1 X-Git-Tag: v1.8.1.6~10 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/357d7f11ba0e2513c2f8bdcaff66aaf7e1f62a14?hp=b04d930bbcd1dc7cbb4524063ec339a8feb3cc12 Merge branch 'ap/maint-update-index-h-is-for-help' into maint-1.8.1 * ap/maint-update-index-h-is-for-help: update-index: allow "-h" to also display options --- diff --git a/Documentation/Makefile b/Documentation/Makefile index 971977b8aa..3c538e3de7 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,7 +1,7 @@ MAN1_TXT= \ $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ $(wildcard git-*.txt)) \ - gitk.txt gitweb.txt git.txt + gitk.txt gitweb.txt git.txt gitremote-helpers.txt MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \ gitrepository-layout.txt gitweb.conf.txt MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \ @@ -13,7 +13,8 @@ MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT) MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) -DOC_HTML=$(MAN_HTML) +OBSOLETE_HTML = git-remote-helpers.html +DOC_HTML=$(MAN_HTML) $(OBSOLETE_HTML) ARTICLES = howto-index ARTICLES += everyday @@ -261,6 +262,12 @@ $(MAN_HTML): %.html : %.txt asciidoc.conf $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< && \ mv $@+ $@ +$(OBSOLETE_HTML): %.html : %.txto asciidoc.conf + $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ + $(ASCIIDOC) -b xhtml11 -f asciidoc.conf \ + $(ASCIIDOC_EXTRA) -agit_version=$(GIT_VERSION) -o $@+ $< && \ + mv $@+ $@ + manpage-base-url.xsl: manpage-base-url.xsl.in sed "s|@@MAN_BASE_URL@@|$(MAN_BASE_URL)|" $< > $@ diff --git a/Documentation/RelNotes/1.8.1.5.txt b/Documentation/RelNotes/1.8.1.5.txt new file mode 100644 index 0000000000..efa68aef22 --- /dev/null +++ b/Documentation/RelNotes/1.8.1.5.txt @@ -0,0 +1,47 @@ +Git 1.8.1.5 Release Notes +========================= + +Fixes since v1.8.1.4 +-------------------- + + * Given a string with a multi-byte character that begins with '-' on + the command line where an option is expected, the option parser + used just one byte of the unknown letter when reporting an error. + + * In v1.8.1, the attribute parser was tightened too restrictive to + error out upon seeing an entry that begins with an ! (exclamation), + which may confuse users to expect a "negative match", which does + not exist. This has been demoted to a warning; such an entry is + still ignored. + + * "git apply --summary" has been taught to make sure the similarity + value shown in its output is sensible, even when the input had a + bogus value. + + * "git clean" showed what it was going to do, but sometimes ended + up finding that it was not allowed to do so, which resulted in a + confusing output (e.g. after saying that it will remove an + untracked directory, it found an embedded git repository there + which it is not allowed to remove). It now performs the actions + and then reports the outcome more faithfully. + + * "git clone" used to allow --bare and --separate-git-dir=$there + options at the same time, which was nonsensical. + + * "git cvsimport" mishandled timestamps at DST boundary. + + * We used to have an arbitrary 32 limit for combined diff input, + resulting in incorrect number of leading colons shown when showing + the "--raw --cc" output. + + * The smart HTTP clients forgot to verify the content-type that comes + back from the server side to make sure that the request is being + handled properly. + + * "git help remote-helpers" failed to find the documentation. + + * "gitweb" pages served over HTTPS, when configured to show picon or + gravatar, referred to these external resources to be fetched via + HTTP, resulting in mixed contents warning in browsers. + +Also contains various documentation fixes. diff --git a/Documentation/config.txt b/Documentation/config.txt index e452ff89ba..c5f1d68a56 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -168,7 +168,7 @@ advice.*:: Advice shown when linkgit:git-merge[1] refuses to merge to avoid overwriting local changes. resolveConflict:: - Advices shown by various commands when conflicts + Advice shown by various commands when conflicts prevent the operation from being performed. implicitIdentity:: Advice on how to set your identity configuration when @@ -525,7 +525,7 @@ core.editor:: `GIT_EDITOR` is not set. See linkgit:git-var[1]. sequence.editor:: - Text editor used by `git rebase -i` for editing the rebase insn file. + Text editor used by `git rebase -i` for editing the rebase instruction file. The value is meant to be interpreted by the shell when it is used. It can be overridden by the `GIT_SEQUENCE_EDITOR` environment variable. When not configured the default commit message editor is used instead. @@ -1758,7 +1758,8 @@ push.default:: + This is currently the default, but Git 2.0 will change the default to `simple`. -* `upstream` - push the current branch to its upstream branch. +* `upstream` - push the current branch to its upstream branch + (`tracking` is a deprecated synonym for this). With this, `git push` will update the same remote ref as the one which is merged by `git pull`, making `push` and `pull` symmetrical. See "branch..merge" for how to configure the upstream branch. diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 39f2c5074c..bbfe8f8f35 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -175,8 +175,8 @@ any of those replacements occurred. --color[=]:: Show colored diff. - The value must be `always` (the default for ``), `never`, or `auto`. - The default value is `never`. + `--color` (i.e. without '=') is the same as `--color=always`. + '' can be one of `always`, `never`, or `auto`. ifdef::git-diff[] It can be changed by the `color.ui` and `color.diff` configuration settings. diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index e4f46bc18d..038514b51e 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -83,7 +83,7 @@ Bisect reset ~~~~~~~~~~~~ After a bisect session, to clean up the bisection state and return to -the original HEAD, issue the following command: +the original HEAD (i.e., to quit bisecting), issue the following command: ------------------------------------------------ $ git bisect reset @@ -284,6 +284,7 @@ EXAMPLES ------------ $ git bisect start HEAD v1.2 -- # HEAD is bad, v1.2 is good $ git bisect run make # "make" builds the app +$ git bisect reset # quit the bisect session ------------ * Automatically bisect a test failure between origin and HEAD: @@ -291,6 +292,7 @@ $ git bisect run make # "make" builds the app ------------ $ git bisect start HEAD origin -- # HEAD is bad, origin is good $ git bisect run make test # "make test" builds and tests +$ git bisect reset # quit the bisect session ------------ * Automatically bisect a broken test case: @@ -302,6 +304,7 @@ make || exit 125 # this skips broken builds ~/check_test_case.sh # does the test case pass? $ git bisect start HEAD HEAD~10 -- # culprit is among the last 10 $ git bisect run ~/test.sh +$ git bisect reset # quit the bisect session ------------ + Here we use a "test.sh" custom script. In this script, if "make" @@ -351,6 +354,7 @@ use `git cherry-pick` instead of `git merge`.) ------------ $ git bisect start HEAD HEAD~10 -- # culprit is among the last 10 $ git bisect run sh -c "make || exit 125; ~/check_test_case.sh" +$ git bisect reset # quit the bisect session ------------ + This shows that you can do without a run script if you write the test @@ -368,6 +372,7 @@ $ git bisect run sh -c ' rm -f tmp.$$ test $rc = 0' +$ git bisect reset # quit the bisect session ------------ + In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 7bdb039d5e..2105638191 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -137,6 +137,8 @@ OPTIONS -m :: --message=:: Use the given as the commit message. + If multiple `-m` options are given, their values are + concatenated as separate paragraphs. -t :: --template=:: diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index 72d6bb612b..711040d2f1 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -81,8 +81,9 @@ OPTIONS that points at object deadbee....). --match :: - Only consider tags matching the given pattern (can be used to avoid - leaking private tags made from the repository). + Only consider tags matching the given `glob(7)` pattern, + excluding the "refs/tags/" prefix. This can be used to avoid + leaking private tags from the repository. --always:: Show uniquely abbreviated commit object as fallback. diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index e2301f5c01..69a40b2107 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -64,8 +64,11 @@ argument is always evaluated in the shell context using the 'eval' command Prior to that, the $GIT_COMMIT environment variable will be set to contain the id of the commit being rewritten. Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, -and GIT_COMMITTER_DATE are set according to the current commit. The values -of these variables after the filters have run, are used for the new commit. +and GIT_COMMITTER_DATE are taken from the current commit and exported to +the environment, in order to affect the author and committer identities of +the replacement commit created by linkgit:git-commit-tree[1] after the +filters have run. + If any evaluation of returns a non-zero exit status, the whole operation will be aborted. @@ -329,6 +332,26 @@ git filter-branch --msg-filter ' ' HEAD~10..HEAD -------------------------------------------------------- +The `--env-filter` option can be used to modify committer and/or author +identity. For example, if you found out that your commits have the wrong +identity due to a misconfigured user.email, you can make a correction, +before publishing the project, like this: + +-------------------------------------------------------- +git filter-branch --env-filter ' + if test "$GIT_AUTHOR_EMAIL" = "root@localhost" + then + GIT_AUTHOR_EMAIL=john@example.com + export GIT_AUTHOR_EMAIL + fi + if test "$GIT_COMMITTER_EMAIL" = "root@localhost" + then + GIT_COMMITTER_EMAIL=john@example.com + export GIT_COMMITTER_EMAIL + fi +' -- --all +-------------------------------------------------------- + To restrict rewriting to only part of the history, specify a revision range in addition to the new branch name. The new branch name will point to the top-most revision that a 'git rev-list' of this range diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index 67fa5ee195..638456b68c 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -218,7 +218,7 @@ $ git merge origin/next ------------------------------------------------ -If you tried a pull which resulted in a complex conflicts and +If you tried a pull which resulted in complex conflicts and would want to start over, you can recover with 'git reset'. diff --git a/Documentation/git-remote-helpers.txt b/Documentation/git-remote-helpers.txt deleted file mode 100644 index 6d696e0f90..0000000000 --- a/Documentation/git-remote-helpers.txt +++ /dev/null @@ -1,423 +0,0 @@ -git-remote-helpers(1) -===================== - -NAME ----- -git-remote-helpers - Helper programs to interact with remote repositories - -SYNOPSIS --------- -[verse] -'git remote-' [] - -DESCRIPTION ------------ - -Remote helper programs are normally not used directly by end users, -but they are invoked by git when it needs to interact with remote -repositories git does not support natively. A given helper will -implement a subset of the capabilities documented here. When git -needs to interact with a repository using a remote helper, it spawns -the helper as an independent process, sends commands to the helper's -standard input, and expects results from the helper's standard -output. Because a remote helper runs as an independent process from -git, there is no need to re-link git to add a new helper, nor any -need to link the helper with the implementation of git. - -Every helper must support the "capabilities" command, which git -uses to determine what other commands the helper will accept. Those -other commands can be used to discover and update remote refs, -transport objects between the object database and the remote repository, -and update the local object store. - -Git comes with a "curl" family of remote helpers, that handle various -transport protocols, such as 'git-remote-http', 'git-remote-https', -'git-remote-ftp' and 'git-remote-ftps'. They implement the capabilities -'fetch', 'option', and 'push'. - -INVOCATION ----------- - -Remote helper programs are invoked with one or (optionally) two -arguments. The first argument specifies a remote repository as in git; -it is either the name of a configured remote or a URL. The second -argument specifies a URL; it is usually of the form -'://
', but any arbitrary string is possible. -The 'GIT_DIR' environment variable is set up for the remote helper -and can be used to determine where to store additional data or from -which directory to invoke auxiliary git commands. - -When git encounters a URL of the form '://
', where -'' is a protocol that it cannot handle natively, it -automatically invokes 'git remote-' with the full URL as -the second argument. If such a URL is encountered directly on the -command line, the first argument is the same as the second, and if it -is encountered in a configured remote, the first argument is the name -of that remote. - -A URL of the form '::
' explicitly instructs git to -invoke 'git remote-' with '
' as the second -argument. If such a URL is encountered directly on the command line, -the first argument is '
', and if it is encountered in a -configured remote, the first argument is the name of that remote. - -Additionally, when a configured remote has 'remote..vcs' set to -'', git explicitly invokes 'git remote-' with -'' as the first argument. If set, the second argument is -'remote..url'; otherwise, the second argument is omitted. - -INPUT FORMAT ------------- - -Git sends the remote helper a list of commands on standard input, one -per line. The first command is always the 'capabilities' command, in -response to which the remote helper must print a list of the -capabilities it supports (see below) followed by a blank line. The -response to the capabilities command determines what commands Git uses -in the remainder of the command stream. - -The command stream is terminated by a blank line. In some cases -(indicated in the documentation of the relevant commands), this blank -line is followed by a payload in some other protocol (e.g., the pack -protocol), while in others it indicates the end of input. - -Capabilities -~~~~~~~~~~~~ - -Each remote helper is expected to support only a subset of commands. -The operations a helper supports are declared to git in the response -to the `capabilities` command (see COMMANDS, below). - -In the following, we list all defined capabilities and for -each we list which commands a helper with that capability -must provide. - -Capabilities for Pushing -^^^^^^^^^^^^^^^^^^^^^^^^ -'connect':: - Can attempt to connect to 'git receive-pack' (for pushing), - 'git upload-pack', etc for communication using - git's native packfile protocol. This - requires a bidirectional, full-duplex connection. -+ -Supported commands: 'connect'. - -'push':: - Can discover remote refs and push local commits and the - history leading up to them to new or existing remote refs. -+ -Supported commands: 'list for-push', 'push'. - -'export':: - Can discover remote refs and push specified objects from a - fast-import stream to remote refs. -+ -Supported commands: 'list for-push', 'export'. - -If a helper advertises 'connect', git will use it if possible and -fall back to another capability if the helper requests so when -connecting (see the 'connect' command under COMMANDS). -When choosing between 'push' and 'export', git prefers 'push'. -Other frontends may have some other order of preference. - - -Capabilities for Fetching -^^^^^^^^^^^^^^^^^^^^^^^^^ -'connect':: - Can try to connect to 'git upload-pack' (for fetching), - 'git receive-pack', etc for communication using the - git's native packfile protocol. This - requires a bidirectional, full-duplex connection. -+ -Supported commands: 'connect'. - -'fetch':: - Can discover remote refs and transfer objects reachable from - them to the local object store. -+ -Supported commands: 'list', 'fetch'. - -'import':: - Can discover remote refs and output objects reachable from - them as a stream in fast-import format. -+ -Supported commands: 'list', 'import'. - -If a helper advertises 'connect', git will use it if possible and -fall back to another capability if the helper requests so when -connecting (see the 'connect' command under COMMANDS). -When choosing between 'fetch' and 'import', git prefers 'fetch'. -Other frontends may have some other order of preference. - -Miscellaneous capabilities -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -'option':: - For specifying settings like `verbosity` (how much output to - write to stderr) and `depth` (how much history is wanted in the - case of a shallow clone) that affect how other commands are - carried out. - -'refspec' :: - This modifies the 'import' capability, allowing the produced - fast-import stream to modify refs in a private namespace - instead of writing to refs/heads or refs/remotes directly. - It is recommended that all importers providing the 'import' - capability use this. -+ -A helper advertising the capability -`refspec refs/heads/*:refs/svn/origin/branches/*` -is saying that, when it is asked to `import refs/heads/topic`, the -stream it outputs will update the `refs/svn/origin/branches/topic` -ref. -+ -This capability can be advertised multiple times. The first -applicable refspec takes precedence. The left-hand of refspecs -advertised with this capability must cover all refs reported by -the list command. If no 'refspec' capability is advertised, -there is an implied `refspec *:*`. - -'bidi-import':: - This modifies the 'import' capability. - The fast-import commands 'cat-blob' and 'ls' can be used by remote-helpers - to retrieve information about blobs and trees that already exist in - fast-import's memory. This requires a channel from fast-import to the - remote-helper. - If it is advertised in addition to "import", git establishes a pipe from - fast-import to the remote-helper's stdin. - It follows that git and fast-import are both connected to the - remote-helper's stdin. Because git can send multiple commands to - the remote-helper it is required that helpers that use 'bidi-import' - buffer all 'import' commands of a batch before sending data to fast-import. - This is to prevent mixing commands and fast-import responses on the - helper's stdin. - -'export-marks' :: - This modifies the 'export' capability, instructing git to dump the - internal marks table to when complete. For details, - read up on '--export-marks=' in linkgit:git-fast-export[1]. - -'import-marks' :: - This modifies the 'export' capability, instructing git to load the - marks specified in before processing any input. For details, - read up on '--import-marks=' in linkgit:git-fast-export[1]. - - - - -COMMANDS --------- - -Commands are given by the caller on the helper's standard input, one per line. - -'capabilities':: - Lists the capabilities of the helper, one per line, ending - with a blank line. Each capability may be preceded with '*', - which marks them mandatory for git versions using the remote - helper to understand. Any unknown mandatory capability is a - fatal error. -+ -Support for this command is mandatory. - -'list':: - Lists the refs, one per line, in the format " - [ ...]". The value may be a hex sha1 hash, "@" for - a symref, or "?" to indicate that the helper could not get the - value of the ref. A space-separated list of attributes follows - the name; unrecognized attributes are ignored. The list ends - with a blank line. -+ -See REF LIST ATTRIBUTES for a list of currently defined attributes. -+ -Supported if the helper has the "fetch" or "import" capability. - -'list for-push':: - Similar to 'list', except that it is used if and only if - the caller wants to the resulting ref list to prepare - push commands. - A helper supporting both push and fetch can use this - to distinguish for which operation the output of 'list' - is going to be used, possibly reducing the amount - of work that needs to be performed. -+ -Supported if the helper has the "push" or "export" capability. - -'option' :: - Sets the transport helper option to . Outputs a - single line containing one of 'ok' (option successfully set), - 'unsupported' (option not recognized) or 'error ' - (option is supported but is not valid - for it). Options should be set before other commands, - and may influence the behavior of those commands. -+ -See OPTIONS for a list of currently defined options. -+ -Supported if the helper has the "option" capability. - -'fetch' :: - Fetches the given object, writing the necessary objects - to the database. Fetch commands are sent in a batch, one - per line, terminated with a blank line. - Outputs a single blank line when all fetch commands in the - same batch are complete. Only objects which were reported - in the output of 'list' with a sha1 may be fetched this way. -+ -Optionally may output a 'lock ' line indicating a file under -GIT_DIR/objects/pack which is keeping a pack until refs can be -suitably updated. -+ -Supported if the helper has the "fetch" capability. - -'push' +::: - Pushes the given local commit or branch to the - remote branch described by . A batch sequence of - one or more 'push' commands is terminated with a blank line - (if there is only one reference to push, a single 'push' command - is followed by a blank line). For example, the following would - be two batches of 'push', the first asking the remote-helper - to push the local ref 'master' to the remote ref 'master' and - the local 'HEAD' to the remote 'branch', and the second - asking to push ref 'foo' to ref 'bar' (forced update requested - by the '+'). -+ ------------- -push refs/heads/master:refs/heads/master -push HEAD:refs/heads/branch -\n -push +refs/heads/foo:refs/heads/bar -\n ------------- -+ -Zero or more protocol options may be entered after the last 'push' -command, before the batch's terminating blank line. -+ -When the push is complete, outputs one or more 'ok ' or -'error ?' lines to indicate success or failure of -each pushed ref. The status report output is terminated by -a blank line. The option field may be quoted in a C -style string if it contains an LF. -+ -Supported if the helper has the "push" capability. - -'import' :: - Produces a fast-import stream which imports the current value - of the named ref. It may additionally import other refs as - needed to construct the history efficiently. The script writes - to a helper-specific private namespace. The value of the named - ref should be written to a location in this namespace derived - by applying the refspecs from the "refspec" capability to the - name of the ref. -+ -Especially useful for interoperability with a foreign versioning -system. -+ -Just like 'push', a batch sequence of one or more 'import' is -terminated with a blank line. For each batch of 'import', the remote -helper should produce a fast-import stream terminated by a 'done' -command. -+ -Note that if the 'bidi-import' capability is used the complete batch -sequence has to be buffered before starting to send data to fast-import -to prevent mixing of commands and fast-import responses on the helper's -stdin. -+ -Supported if the helper has the "import" capability. - -'export':: - Instructs the remote helper that any subsequent input is - part of a fast-import stream (generated by 'git fast-export') - containing objects which should be pushed to the remote. -+ -Especially useful for interoperability with a foreign versioning -system. -+ -The 'export-marks' and 'import-marks' capabilities, if specified, -affect this command in so far as they are passed on to 'git -fast-export', which then will load/store a table of marks for -local objects. This can be used to implement for incremental -operations. -+ -Supported if the helper has the "export" capability. - -'connect' :: - Connects to given service. Standard input and standard output - of helper are connected to specified service (git prefix is - included in service name so e.g. fetching uses 'git-upload-pack' - as service) on remote side. Valid replies to this command are - empty line (connection established), 'fallback' (no smart - transport support, fall back to dumb transports) and just - exiting with error message printed (can't connect, don't - bother trying to fall back). After line feed terminating the - positive (empty) response, the output of service starts. After - the connection ends, the remote helper exits. -+ -Supported if the helper has the "connect" capability. - -If a fatal error occurs, the program writes the error message to -stderr and exits. The caller should expect that a suitable error -message has been printed if the child closes the connection without -completing a valid response for the current command. - -Additional commands may be supported, as may be determined from -capabilities reported by the helper. - -REF LIST ATTRIBUTES -------------------- - -The 'list' command produces a list of refs in which each ref -may be followed by a list of attributes. The following ref list -attributes are defined. - -'unchanged':: - This ref is unchanged since the last import or fetch, although - the helper cannot necessarily determine what value that produced. - -OPTIONS -------- - -The following options are defined and (under suitable circumstances) -set by git if the remote helper has the 'option' capability. - -'option verbosity' :: - Changes the verbosity of messages displayed by the helper. - A value of 0 for means that processes operate - quietly, and the helper produces only error output. - 1 is the default level of verbosity, and higher values - of correspond to the number of -v flags passed on the - command line. - -'option progress' \{'true'|'false'\}:: - Enables (or disables) progress messages displayed by the - transport helper during a command. - -'option depth' :: - Deepens the history of a shallow repository. - -'option followtags' \{'true'|'false'\}:: - If enabled the helper should automatically fetch annotated - tag objects if the object the tag points at was transferred - during the fetch command. If the tag is not fetched by - the helper a second fetch command will usually be sent to - ask for the tag specifically. Some helpers may be able to - use this option to avoid a second network connection. - -'option dry-run' \{'true'|'false'\}: - If true, pretend the operation completed successfully, - but don't actually change any repository data. For most - helpers this only applies to the 'push', if supported. - -'option servpath ':: - Sets service path (--upload-pack, --receive-pack etc.) for - next connect. Remote helper may support this option, but - must not rely on this option being set before - connect request occurs. - -SEE ALSO --------- -linkgit:git-remote[1] - -linkgit:git-remote-testgit[1] - -GIT ---- -Part of the linkgit:git[1] suite diff --git a/Documentation/git-remote-helpers.txto b/Documentation/git-remote-helpers.txto new file mode 100644 index 0000000000..49233f5d26 --- /dev/null +++ b/Documentation/git-remote-helpers.txto @@ -0,0 +1,9 @@ +git-remote-helpers +================== + +This document has been moved to linkgit:gitremote-helpers[1]. + +Please let the owners of the referring site know so that they can update the +link you clicked to get here. + +Thanks. diff --git a/Documentation/git-remote-testgit.txt b/Documentation/git-remote-testgit.txt index 2a67d456a3..4c871b92e9 100644 --- a/Documentation/git-remote-testgit.txt +++ b/Documentation/git-remote-testgit.txt @@ -23,7 +23,7 @@ The best way to learn more is to read the comments and source code in SEE ALSO -------- -linkgit:git-remote-helpers[1] +linkgit:gitremote-helpers[1] GIT --- diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index b1de3bade7..349378448c 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -13,7 +13,7 @@ SYNOPSIS [--reference ] [--] [] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] -'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] +'git submodule' [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) ] [commit] [--] [...] diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index 6470cffd32..ea28e39c1b 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -126,6 +126,12 @@ This option is only applicable when listing tags without annotation lines. linkgit:git-check-ref-format[1]. Some of these checks may restrict the characters allowed in a tag name. +:: +:: + The object that the new tag will refer to, usually a commit. + Defaults to HEAD. + + CONFIGURATION ------------- By default, 'git tag' in sign-with-default mode (-s) will use your diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 9d0b1515c5..dd36d13285 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -145,7 +145,15 @@ you will need to handle the situation manually. --index-version :: Write the resulting index out in the named on-disk format version. - The current default version is 2. + Supported versions are 2, 3 and 4. The current default version is 2 + or 3, depending on whether extra features are used, such as + `git add -N`. ++ +Version 4 performs a simple pathname compression that reduces index +size by 30%-50% on large repositories, which results in faster load +time. Version 4 is relatively young (first released in in 1.8.0 in +October 2012). Other Git implementations such as JGit and libgit2 +may not support it yet. -z:: Only meaningful with `--stdin` or `--index-info`; paths are diff --git a/Documentation/git.txt b/Documentation/git.txt index da0115f3d0..98a45addf5 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.8.1.4/git.html[documentation for release 1.8.1.4] +* link:v1.8.1.5/git.html[documentation for release 1.8.1.5] * release notes for + link:RelNotes/1.8.1.5.txt[1.8.1.5], link:RelNotes/1.8.1.4.txt[1.8.1.4], link:RelNotes/1.8.1.3.txt[1.8.1.3], link:RelNotes/1.8.1.2.txt[1.8.1.2], @@ -531,10 +532,9 @@ include::cmds-purehelpers.txt[] Configuration Mechanism ----------------------- -Starting from 0.99.9 (actually mid 0.99.8.GIT), `.git/config` file -is used to hold per-repository configuration options. It is a -simple text file modeled after `.ini` format familiar to some -people. Here is an example: +Git uses a simple text format to store customizations that are per +repository and are per user. Such a configuration file may look +like this: ------------ # @@ -549,13 +549,13 @@ people. Here is an example: ; user identity [user] name = "Junio C Hamano" - email = "junkio@twinsun.com" + email = "gitster@pobox.com" ------------ Various commands read from the configuration file and adjust their operation accordingly. See linkgit:git-config[1] for a -list. +list and more details about the configuration mechanism. Identifier Terminology @@ -674,12 +674,19 @@ git so take care if using Cogito etc. The '--namespace' command-line option also sets this value. 'GIT_CEILING_DIRECTORIES':: - This should be a colon-separated list of absolute paths. - If set, it is a list of directories that git should not chdir - up into while looking for a repository directory. - It will not exclude the current working directory or - a GIT_DIR set on the command line or in the environment. - (Useful for excluding slow-loading network directories.) + This should be a colon-separated list of absolute paths. If + set, it is a list of directories that git should not chdir up + into while looking for a repository directory (useful for + excluding slow-loading network directories). It will not + exclude the current working directory or a GIT_DIR set on the + command line or in the environment. Normally, Git has to read + the entries in this list and resolve any symlink that + might be present in order to compare them with the current + directory. However, if even this access is slow, you + can add an empty entry to the list to tell Git that the + subsequent entries are not symlinks and needn't be resolved; + e.g., + 'GIT_CEILING_DIRECTORIES=/maybe/symlink::/very/slow/non/symlink'. 'GIT_DISCOVERY_ACROSS_FILESYSTEM':: When run in a directory that does not have ".git" repository @@ -757,9 +764,12 @@ other If this environment variable is set then 'git fetch' and 'git push' will use this command instead of 'ssh' when they need to connect to a remote system. - The '$GIT_SSH' command will be given exactly two arguments: - the 'username@host' (or just 'host') from the URL and the - shell command to execute on that remote system. + The '$GIT_SSH' command will be given exactly two or + four arguments: the 'username@host' (or just 'host') + from the URL and the shell command to execute on that + remote system, optionally preceded by '-p' (literally) and + the 'port' from the URL when it specifies something other + than the default SSH port. + To pass options to the program that you want to list in GIT_SSH you will need to wrap the program and options into a shell script, diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index b9003fed24..4eed86b2a4 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -140,9 +140,11 @@ the outcome of 'git commit'. pre-rebase ~~~~~~~~~~ -This hook is called by 'git rebase' and can be used to prevent a branch -from getting rebased. - +This hook is called by 'git rebase' and can be used to prevent a +branch from getting rebased. The hook may be called with one or +two parameters. The first parameter is the upstream from which +the series was forked. The second parameter is the branch being +rebased, and is not set when rebasing the current branch. post-checkout ~~~~~~~~~~~~~ @@ -336,7 +338,7 @@ preceding SP is also omitted. Currently, no commands pass any 'extra-info'. The hook always runs after the automatic note copying (see -"notes.rewrite." in linkgit:git-config.txt) has happened, and +"notes.rewrite." in linkgit:git-config.txt[1]) has happened, and thus has access to these notes. The following command-specific comments apply: diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt new file mode 100644 index 0000000000..0f21367ca5 --- /dev/null +++ b/Documentation/gitremote-helpers.txt @@ -0,0 +1,423 @@ +gitremote-helpers(1) +==================== + +NAME +---- +gitremote-helpers - Helper programs to interact with remote repositories + +SYNOPSIS +-------- +[verse] +'git remote-' [] + +DESCRIPTION +----------- + +Remote helper programs are normally not used directly by end users, +but they are invoked by git when it needs to interact with remote +repositories git does not support natively. A given helper will +implement a subset of the capabilities documented here. When git +needs to interact with a repository using a remote helper, it spawns +the helper as an independent process, sends commands to the helper's +standard input, and expects results from the helper's standard +output. Because a remote helper runs as an independent process from +git, there is no need to re-link git to add a new helper, nor any +need to link the helper with the implementation of git. + +Every helper must support the "capabilities" command, which git +uses to determine what other commands the helper will accept. Those +other commands can be used to discover and update remote refs, +transport objects between the object database and the remote repository, +and update the local object store. + +Git comes with a "curl" family of remote helpers, that handle various +transport protocols, such as 'git-remote-http', 'git-remote-https', +'git-remote-ftp' and 'git-remote-ftps'. They implement the capabilities +'fetch', 'option', and 'push'. + +INVOCATION +---------- + +Remote helper programs are invoked with one or (optionally) two +arguments. The first argument specifies a remote repository as in git; +it is either the name of a configured remote or a URL. The second +argument specifies a URL; it is usually of the form +'://
', but any arbitrary string is possible. +The 'GIT_DIR' environment variable is set up for the remote helper +and can be used to determine where to store additional data or from +which directory to invoke auxiliary git commands. + +When git encounters a URL of the form '://
', where +'' is a protocol that it cannot handle natively, it +automatically invokes 'git remote-' with the full URL as +the second argument. If such a URL is encountered directly on the +command line, the first argument is the same as the second, and if it +is encountered in a configured remote, the first argument is the name +of that remote. + +A URL of the form '::
' explicitly instructs git to +invoke 'git remote-' with '
' as the second +argument. If such a URL is encountered directly on the command line, +the first argument is '
', and if it is encountered in a +configured remote, the first argument is the name of that remote. + +Additionally, when a configured remote has 'remote..vcs' set to +'', git explicitly invokes 'git remote-' with +'' as the first argument. If set, the second argument is +'remote..url'; otherwise, the second argument is omitted. + +INPUT FORMAT +------------ + +Git sends the remote helper a list of commands on standard input, one +per line. The first command is always the 'capabilities' command, in +response to which the remote helper must print a list of the +capabilities it supports (see below) followed by a blank line. The +response to the capabilities command determines what commands Git uses +in the remainder of the command stream. + +The command stream is terminated by a blank line. In some cases +(indicated in the documentation of the relevant commands), this blank +line is followed by a payload in some other protocol (e.g., the pack +protocol), while in others it indicates the end of input. + +Capabilities +~~~~~~~~~~~~ + +Each remote helper is expected to support only a subset of commands. +The operations a helper supports are declared to git in the response +to the `capabilities` command (see COMMANDS, below). + +In the following, we list all defined capabilities and for +each we list which commands a helper with that capability +must provide. + +Capabilities for Pushing +^^^^^^^^^^^^^^^^^^^^^^^^ +'connect':: + Can attempt to connect to 'git receive-pack' (for pushing), + 'git upload-pack', etc for communication using + git's native packfile protocol. This + requires a bidirectional, full-duplex connection. ++ +Supported commands: 'connect'. + +'push':: + Can discover remote refs and push local commits and the + history leading up to them to new or existing remote refs. ++ +Supported commands: 'list for-push', 'push'. + +'export':: + Can discover remote refs and push specified objects from a + fast-import stream to remote refs. ++ +Supported commands: 'list for-push', 'export'. + +If a helper advertises 'connect', git will use it if possible and +fall back to another capability if the helper requests so when +connecting (see the 'connect' command under COMMANDS). +When choosing between 'push' and 'export', git prefers 'push'. +Other frontends may have some other order of preference. + + +Capabilities for Fetching +^^^^^^^^^^^^^^^^^^^^^^^^^ +'connect':: + Can try to connect to 'git upload-pack' (for fetching), + 'git receive-pack', etc for communication using the + git's native packfile protocol. This + requires a bidirectional, full-duplex connection. ++ +Supported commands: 'connect'. + +'fetch':: + Can discover remote refs and transfer objects reachable from + them to the local object store. ++ +Supported commands: 'list', 'fetch'. + +'import':: + Can discover remote refs and output objects reachable from + them as a stream in fast-import format. ++ +Supported commands: 'list', 'import'. + +If a helper advertises 'connect', git will use it if possible and +fall back to another capability if the helper requests so when +connecting (see the 'connect' command under COMMANDS). +When choosing between 'fetch' and 'import', git prefers 'fetch'. +Other frontends may have some other order of preference. + +Miscellaneous capabilities +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +'option':: + For specifying settings like `verbosity` (how much output to + write to stderr) and `depth` (how much history is wanted in the + case of a shallow clone) that affect how other commands are + carried out. + +'refspec' :: + This modifies the 'import' capability, allowing the produced + fast-import stream to modify refs in a private namespace + instead of writing to refs/heads or refs/remotes directly. + It is recommended that all importers providing the 'import' + capability use this. ++ +A helper advertising the capability +`refspec refs/heads/*:refs/svn/origin/branches/*` +is saying that, when it is asked to `import refs/heads/topic`, the +stream it outputs will update the `refs/svn/origin/branches/topic` +ref. ++ +This capability can be advertised multiple times. The first +applicable refspec takes precedence. The left-hand of refspecs +advertised with this capability must cover all refs reported by +the list command. If no 'refspec' capability is advertised, +there is an implied `refspec *:*`. + +'bidi-import':: + This modifies the 'import' capability. + The fast-import commands 'cat-blob' and 'ls' can be used by remote-helpers + to retrieve information about blobs and trees that already exist in + fast-import's memory. This requires a channel from fast-import to the + remote-helper. + If it is advertised in addition to "import", git establishes a pipe from + fast-import to the remote-helper's stdin. + It follows that git and fast-import are both connected to the + remote-helper's stdin. Because git can send multiple commands to + the remote-helper it is required that helpers that use 'bidi-import' + buffer all 'import' commands of a batch before sending data to fast-import. + This is to prevent mixing commands and fast-import responses on the + helper's stdin. + +'export-marks' :: + This modifies the 'export' capability, instructing git to dump the + internal marks table to when complete. For details, + read up on '--export-marks=' in linkgit:git-fast-export[1]. + +'import-marks' :: + This modifies the 'export' capability, instructing git to load the + marks specified in before processing any input. For details, + read up on '--import-marks=' in linkgit:git-fast-export[1]. + + + + +COMMANDS +-------- + +Commands are given by the caller on the helper's standard input, one per line. + +'capabilities':: + Lists the capabilities of the helper, one per line, ending + with a blank line. Each capability may be preceded with '*', + which marks them mandatory for git versions using the remote + helper to understand. Any unknown mandatory capability is a + fatal error. ++ +Support for this command is mandatory. + +'list':: + Lists the refs, one per line, in the format " + [ ...]". The value may be a hex sha1 hash, "@" for + a symref, or "?" to indicate that the helper could not get the + value of the ref. A space-separated list of attributes follows + the name; unrecognized attributes are ignored. The list ends + with a blank line. ++ +See REF LIST ATTRIBUTES for a list of currently defined attributes. ++ +Supported if the helper has the "fetch" or "import" capability. + +'list for-push':: + Similar to 'list', except that it is used if and only if + the caller wants to the resulting ref list to prepare + push commands. + A helper supporting both push and fetch can use this + to distinguish for which operation the output of 'list' + is going to be used, possibly reducing the amount + of work that needs to be performed. ++ +Supported if the helper has the "push" or "export" capability. + +'option' :: + Sets the transport helper option to . Outputs a + single line containing one of 'ok' (option successfully set), + 'unsupported' (option not recognized) or 'error ' + (option is supported but is not valid + for it). Options should be set before other commands, + and may influence the behavior of those commands. ++ +See OPTIONS for a list of currently defined options. ++ +Supported if the helper has the "option" capability. + +'fetch' :: + Fetches the given object, writing the necessary objects + to the database. Fetch commands are sent in a batch, one + per line, terminated with a blank line. + Outputs a single blank line when all fetch commands in the + same batch are complete. Only objects which were reported + in the output of 'list' with a sha1 may be fetched this way. ++ +Optionally may output a 'lock ' line indicating a file under +GIT_DIR/objects/pack which is keeping a pack until refs can be +suitably updated. ++ +Supported if the helper has the "fetch" capability. + +'push' +::: + Pushes the given local commit or branch to the + remote branch described by . A batch sequence of + one or more 'push' commands is terminated with a blank line + (if there is only one reference to push, a single 'push' command + is followed by a blank line). For example, the following would + be two batches of 'push', the first asking the remote-helper + to push the local ref 'master' to the remote ref 'master' and + the local 'HEAD' to the remote 'branch', and the second + asking to push ref 'foo' to ref 'bar' (forced update requested + by the '+'). ++ +------------ +push refs/heads/master:refs/heads/master +push HEAD:refs/heads/branch +\n +push +refs/heads/foo:refs/heads/bar +\n +------------ ++ +Zero or more protocol options may be entered after the last 'push' +command, before the batch's terminating blank line. ++ +When the push is complete, outputs one or more 'ok ' or +'error ?' lines to indicate success or failure of +each pushed ref. The status report output is terminated by +a blank line. The option field may be quoted in a C +style string if it contains an LF. ++ +Supported if the helper has the "push" capability. + +'import' :: + Produces a fast-import stream which imports the current value + of the named ref. It may additionally import other refs as + needed to construct the history efficiently. The script writes + to a helper-specific private namespace. The value of the named + ref should be written to a location in this namespace derived + by applying the refspecs from the "refspec" capability to the + name of the ref. ++ +Especially useful for interoperability with a foreign versioning +system. ++ +Just like 'push', a batch sequence of one or more 'import' is +terminated with a blank line. For each batch of 'import', the remote +helper should produce a fast-import stream terminated by a 'done' +command. ++ +Note that if the 'bidi-import' capability is used the complete batch +sequence has to be buffered before starting to send data to fast-import +to prevent mixing of commands and fast-import responses on the helper's +stdin. ++ +Supported if the helper has the "import" capability. + +'export':: + Instructs the remote helper that any subsequent input is + part of a fast-import stream (generated by 'git fast-export') + containing objects which should be pushed to the remote. ++ +Especially useful for interoperability with a foreign versioning +system. ++ +The 'export-marks' and 'import-marks' capabilities, if specified, +affect this command in so far as they are passed on to 'git +fast-export', which then will load/store a table of marks for +local objects. This can be used to implement for incremental +operations. ++ +Supported if the helper has the "export" capability. + +'connect' :: + Connects to given service. Standard input and standard output + of helper are connected to specified service (git prefix is + included in service name so e.g. fetching uses 'git-upload-pack' + as service) on remote side. Valid replies to this command are + empty line (connection established), 'fallback' (no smart + transport support, fall back to dumb transports) and just + exiting with error message printed (can't connect, don't + bother trying to fall back). After line feed terminating the + positive (empty) response, the output of service starts. After + the connection ends, the remote helper exits. ++ +Supported if the helper has the "connect" capability. + +If a fatal error occurs, the program writes the error message to +stderr and exits. The caller should expect that a suitable error +message has been printed if the child closes the connection without +completing a valid response for the current command. + +Additional commands may be supported, as may be determined from +capabilities reported by the helper. + +REF LIST ATTRIBUTES +------------------- + +The 'list' command produces a list of refs in which each ref +may be followed by a list of attributes. The following ref list +attributes are defined. + +'unchanged':: + This ref is unchanged since the last import or fetch, although + the helper cannot necessarily determine what value that produced. + +OPTIONS +------- + +The following options are defined and (under suitable circumstances) +set by git if the remote helper has the 'option' capability. + +'option verbosity' :: + Changes the verbosity of messages displayed by the helper. + A value of 0 for means that processes operate + quietly, and the helper produces only error output. + 1 is the default level of verbosity, and higher values + of correspond to the number of -v flags passed on the + command line. + +'option progress' \{'true'|'false'\}:: + Enables (or disables) progress messages displayed by the + transport helper during a command. + +'option depth' :: + Deepens the history of a shallow repository. + +'option followtags' \{'true'|'false'\}:: + If enabled the helper should automatically fetch annotated + tag objects if the object the tag points at was transferred + during the fetch command. If the tag is not fetched by + the helper a second fetch command will usually be sent to + ask for the tag specifically. Some helpers may be able to + use this option to avoid a second network connection. + +'option dry-run' \{'true'|'false'\}: + If true, pretend the operation completed successfully, + but don't actually change any repository data. For most + helpers this only applies to the 'push', if supported. + +'option servpath ':: + Sets service path (--upload-pack, --receive-pack etc.) for + next connect. Remote helper may support this option, but + must not rely on this option being set before + connect request occurs. + +SEE ALSO +-------- +linkgit:git-remote[1] + +linkgit:git-remote-testgit[1] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index 991fcd8f3f..013f0de798 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -88,10 +88,10 @@ some output processing may assume ref names in UTF-8. The construct '@\{-\}' means the th branch checked out before the current one. -'@\{upstream\}', e.g. 'master@\{upstream\}', '@\{u\}':: - The suffix '@\{upstream\}' to a ref (short form '@\{u\}') refers to - the branch the ref is set to build on top of. A missing ref defaults - to the current branch. +'@\{upstream\}', e.g. 'master@\{upstream\}', '@\{u\}':: + The suffix '@\{upstream\}' to a branchname (short form '@\{u\}') + refers to the branch that the branch specified by branchname is set to build on + top of. A missing branchname defaults to the current one. '{caret}', e.g. 'HEAD{caret}, v1.5.1{caret}0':: A suffix '{caret}' to a revision parameter means the first parent of diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt index 7324154838..dcd51b97d9 100644 --- a/Documentation/technical/index-format.txt +++ b/Documentation/technical/index-format.txt @@ -12,7 +12,7 @@ GIT index format The signature is { 'D', 'I', 'R', 'C' } (stands for "dircache") 4-byte version number: - The current supported versions are 2 and 3. + The current supported versions are 2, 3 and 4. 32-bit number of index entries. @@ -93,8 +93,8 @@ GIT index format 12-bit name length if the length is less than 0xFFF; otherwise 0xFFF is stored in this field. - (Version 3) A 16-bit field, only applicable if the "extended flag" - above is 1, split into (high to low bits). + (Version 3 or later) A 16-bit field, only applicable if the + "extended flag" above is 1, split into (high to low bits). 1-bit reserved for future diff --git a/Documentation/urls.txt b/Documentation/urls.txt index 1d15ee7e52..cea5462ff8 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -55,7 +55,7 @@ may be used: where
may be a path, a server and path, or an arbitrary URL-like string recognized by the specific remote helper being -invoked. See linkgit:git-remote-helpers[1] for details. +invoked. See linkgit:gitremote-helpers[1] for details. If there are a large number of similarly-named remote repositories and you want to use a different format for them (such that the URLs you diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index 52c8523c7d..988c13ff4c 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -2004,9 +2004,10 @@ handling this case. Note that the target of a "push" is normally a <> repository. You can also push to a -repository that has a checked-out working tree, but the working tree -will not be updated by the push. This may lead to unexpected results if -the branch you push to is the currently checked-out branch! +repository that has a checked-out working tree, but a push to update the +currently checked-out branch is denied by default to prevent confusion. +See the description of the receive.denyCurrentBranch option +in linkgit:git-config[1] for details. As with `git fetch`, you may also set up configuration options to save typing; so, for example: @@ -2305,17 +2306,13 @@ branch and then merge into each of the test and release branches. For these changes, just apply directly to the "release" branch, and then merge that into the "test" branch. -To create diffstat and shortlog summaries of changes to include in a "please -pull" request to Linus you can use: +After pushing your work to `mytree`, you can use +linkgit:git-request-pull[1] to prepare a "please pull" request message +to send to Linus: ------------------------------------------------- -$ git diff --stat origin..release -------------------------------------------------- - -and - -------------------------------------------------- -$ git log -p origin..release | git shortlog +$ git push mytree +$ git request-pull origin mytree release ------------------------------------------------- Here are some of the scripts that simplify all this even further. @@ -2556,6 +2553,12 @@ return mywork to the state it had before you started the rebase: $ git rebase --abort ------------------------------------------------- +If you need to reorder or edit a number of commits in a branch, it may +be easier to use `git rebase -i`, which allows you to reorder and +squash commits, as well as marking them for individual editing during +the rebase. See <> for details, and +<> for alternatives. + [[rewriting-one-commit]] Rewriting a single commit ------------------------- @@ -2569,72 +2572,89 @@ $ git commit --amend which will replace the old commit by a new commit incorporating your changes, giving you a chance to edit the old commit message first. +This is useful for fixing typos in your last commit, or for adjusting +the patch contents of a poorly staged commit. -You can also use a combination of this and linkgit:git-rebase[1] to -replace a commit further back in your history and recreate the -intervening changes on top of it. First, tag the problematic commit -with +If you need to amend commits from deeper in your history, you can +use <>. -------------------------------------------------- -$ git tag bad mywork~5 -------------------------------------------------- - -(Either gitk or `git log` may be useful for finding the commit.) +[[reordering-patch-series]] +Reordering or selecting from a patch series +------------------------------------------- -Then check out that commit, edit it, and rebase the rest of the series -on top of it (note that we could check out the commit on a temporary -branch, but instead we're using a <>): +Sometimes you want to edit a commit deeper in your history. One +approach is to use `git format-patch` to create a series of patches +and then reset the state to before the patches: ------------------------------------------------- -$ git checkout bad -$ # make changes here and update the index -$ git commit --amend -$ git rebase --onto HEAD bad mywork +$ git format-patch origin +$ git reset --hard origin ------------------------------------------------- -When you're done, you'll be left with mywork checked out, with the top -patches on mywork reapplied on top of your modified commit. You can -then clean up with +Then modify, reorder, or eliminate patches as needed before applying +them again with linkgit:git-am[1]: ------------------------------------------------- -$ git tag -d bad +$ git am *.patch ------------------------------------------------- -Note that the immutable nature of git history means that you haven't really -"modified" existing commits; instead, you have replaced the old commits with -new commits having new object names. +[[interactive-rebase]] +Using interactive rebases +------------------------- -[[reordering-patch-series]] -Reordering or selecting from a patch series -------------------------------------------- +You can also edit a patch series with an interactive rebase. This is +the same as <>, so use whichever interface you like best. -Given one existing commit, the linkgit:git-cherry-pick[1] command -allows you to apply the change introduced by that commit and create a -new commit that records it. So, for example, if "mywork" points to a -series of patches on top of "origin", you might do something like: +Rebase your current HEAD on the last commit you want to retain as-is. +For example, if you want to reorder the last 5 commits, use: ------------------------------------------------- -$ git checkout -b mywork-new origin -$ gitk origin..mywork & +$ git rebase -i HEAD~5 ------------------------------------------------- -and browse through the list of patches in the mywork branch using gitk, -applying them (possibly in a different order) to mywork-new using -cherry-pick, and possibly modifying them as you go using `git commit --amend`. -The linkgit:git-gui[1] command may also help as it allows you to -individually select diff hunks for inclusion in the index (by -right-clicking on the diff hunk and choosing "Stage Hunk for Commit"). - -Another technique is to use `git format-patch` to create a series of -patches, then reset the state to before the patches: +This will open your editor with a list of steps to be taken to perform +your rebase. ------------------------------------------------- -$ git format-patch origin -$ git reset --hard origin -------------------------------------------------- +pick deadbee The oneline of this commit +pick fa1afe1 The oneline of the next commit +... -Then modify, reorder, or eliminate patches as preferred before applying -them again with linkgit:git-am[1]. +# Rebase c0ffeee..deadbee onto c0ffeee +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +# Note that empty commits are commented out +------------------------------------------------- + +As explained in the comments, you can reorder commits, squash them +together, edit commit messages, etc. by editing the list. Once you +are satisfied, save the list and close your editor, and the rebase +will begin. + +The rebase will stop where `pick` has been replaced with `edit` or +when a step in the list fails to mechanically resolve conflicts and +needs your help. When you are done editing and/or resolving conflicts +you can continue with `git rebase --continue`. If you decide that +things are getting too hairy, you can always bail out with `git rebase +--abort`. Even after the rebase is complete, you can still recover +the original branch by using the <>. + +For a more detailed discussion of the procedure and additional tips, +see the "INTERACTIVE MODE" section of linkgit:git-rebase[1]. [[patch-series-tools]] Other tools @@ -3720,7 +3740,9 @@ module a NOTE: The changes are still visible in the submodule's reflog. -This is not the case if you did not commit your changes. +If you have uncommitted changes in your submodule working tree, `git +submodule update` will not overwrite them. Instead, you get the usual +warning about not being able switch from a dirty branch. [[low-level-operations]] Low-level git operations diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index dcd3595f27..6f09e2ff8b 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.8.1.4 +DEF_VER=v1.8.1.5 LF=' ' diff --git a/Makefile b/Makefile index 4bb3cf1367..5be54584b7 100644 --- a/Makefile +++ b/Makefile @@ -583,22 +583,6 @@ LIB_FILE = libgit.a XDIFF_LIB = xdiff/lib.a VCSSVN_LIB = vcs-svn/lib.a -LIB_H += xdiff/xinclude.h -LIB_H += xdiff/xmacros.h -LIB_H += xdiff/xdiff.h -LIB_H += xdiff/xtypes.h -LIB_H += xdiff/xutils.h -LIB_H += xdiff/xprepare.h -LIB_H += xdiff/xdiffi.h -LIB_H += xdiff/xemit.h - -LIB_H += vcs-svn/line_buffer.h -LIB_H += vcs-svn/sliding_window.h -LIB_H += vcs-svn/repo_tree.h -LIB_H += vcs-svn/fast_export.h -LIB_H += vcs-svn/svndiff.h -LIB_H += vcs-svn/svndump.h - GENERATED_H += common-cmds.h LIB_H += advice.h @@ -699,10 +683,23 @@ LIB_H += url.h LIB_H += userdiff.h LIB_H += utf8.h LIB_H += varint.h +LIB_H += vcs-svn/fast_export.h +LIB_H += vcs-svn/line_buffer.h +LIB_H += vcs-svn/repo_tree.h +LIB_H += vcs-svn/sliding_window.h +LIB_H += vcs-svn/svndiff.h +LIB_H += vcs-svn/svndump.h LIB_H += walker.h LIB_H += wt-status.h LIB_H += xdiff-interface.h LIB_H += xdiff/xdiff.h +LIB_H += xdiff/xdiffi.h +LIB_H += xdiff/xemit.h +LIB_H += xdiff/xinclude.h +LIB_H += xdiff/xmacros.h +LIB_H += xdiff/xprepare.h +LIB_H += xdiff/xtypes.h +LIB_H += xdiff/xutils.h LIB_OBJS += abspath.o LIB_OBJS += advice.o @@ -2272,12 +2269,14 @@ $(patsubst %.py,%,$(SCRIPT_PYTHON)): % : unimplemented.sh mv $@+ $@ endif # NO_PYTHON +CONFIGURE_RECIPE = $(RM) configure configure.ac+ && \ + sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ + configure.ac >configure.ac+ && \ + autoconf -o configure configure.ac+ && \ + $(RM) configure.ac+ + configure: configure.ac GIT-VERSION-FILE - $(QUIET_GEN)$(RM) $@ $<+ && \ - sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - $< > $<+ && \ - autoconf -o $@ $<+ && \ - $(RM) $<+ + $(QUIET_GEN)$(CONFIGURE_RECIPE) ifdef AUTOCONFIGURED # We avoid depending on 'configure' here, because it gets rebuilt @@ -2286,7 +2285,7 @@ ifdef AUTOCONFIGURED # do want to recheck when the platform/environment detection logic # changes, hence this depends on configure.ac. config.status: configure.ac - $(QUIET_GEN)$(MAKE) configure && \ + $(QUIET_GEN)$(CONFIGURE_RECIPE) && \ if test -f config.status; then \ ./config.status --recheck; \ else \ diff --git a/RelNotes b/RelNotes index ad613ead7b..3c65929a74 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/1.8.1.4.txt \ No newline at end of file +Documentation/RelNotes/1.8.1.5.txt \ No newline at end of file diff --git a/attr.c b/attr.c index 8985c5c25b..d181d98b0e 100644 --- a/attr.c +++ b/attr.c @@ -255,9 +255,11 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, &res->u.pat.patternlen, &res->u.pat.flags, &res->u.pat.nowildcardlen); - if (res->u.pat.flags & EXC_FLAG_NEGATIVE) - die(_("Negative patterns are forbidden in git attributes\n" - "Use '\\!' for literal leading exclamation.")); + if (res->u.pat.flags & EXC_FLAG_NEGATIVE) { + warning(_("Negative patterns are ignored in git attributes\n" + "Use '\\!' for literal leading exclamation.")); + return NULL; + } } res->is_macro = is_macro; res->num_attr = num_attr; diff --git a/builtin/apply.c b/builtin/apply.c index 9706ca73ab..080ce2ea3e 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -1041,15 +1041,17 @@ static int gitdiff_renamedst(const char *line, struct patch *patch) static int gitdiff_similarity(const char *line, struct patch *patch) { - if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX) - patch->score = 0; + unsigned long val = strtoul(line, NULL, 10); + if (val <= 100) + patch->score = val; return 0; } static int gitdiff_dissimilarity(const char *line, struct patch *patch) { - if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX) - patch->score = 0; + unsigned long val = strtoul(line, NULL, 10); + if (val <= 100) + patch->score = val; return 0; } diff --git a/builtin/clean.c b/builtin/clean.c index 69c1cda906..f4b760bf3d 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -10,6 +10,7 @@ #include "cache.h" #include "dir.h" #include "parse-options.h" +#include "refs.h" #include "string-list.h" #include "quote.h" @@ -20,6 +21,12 @@ static const char *const builtin_clean_usage[] = { NULL }; +static const char *msg_remove = N_("Removing %s\n"); +static const char *msg_would_remove = N_("Would remove %s\n"); +static const char *msg_skip_git_dir = N_("Skipping repository %s\n"); +static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n"); +static const char *msg_warn_remove_failed = N_("failed to remove %s"); + static int git_clean_config(const char *var, const char *value, void *cb) { if (!strcmp(var, "clean.requireforce")) @@ -34,11 +41,112 @@ static int exclude_cb(const struct option *opt, const char *arg, int unset) return 0; } +static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag, + int dry_run, int quiet, int *dir_gone) +{ + DIR *dir; + struct strbuf quoted = STRBUF_INIT; + struct dirent *e; + int res = 0, ret = 0, gone = 1, original_len = path->len, len, i; + unsigned char submodule_head[20]; + struct string_list dels = STRING_LIST_INIT_DUP; + + *dir_gone = 1; + + if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) && + !resolve_gitlink_ref(path->buf, "HEAD", submodule_head)) { + if (!quiet) { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + printf(dry_run ? _(msg_would_skip_git_dir) : _(msg_skip_git_dir), + quoted.buf); + } + + *dir_gone = 0; + return 0; + } + + dir = opendir(path->buf); + if (!dir) { + /* an empty dir could be removed even if it is unreadble */ + res = dry_run ? 0 : rmdir(path->buf); + if (res) { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + warning(_(msg_warn_remove_failed), quoted.buf); + *dir_gone = 0; + } + return res; + } + + if (path->buf[original_len - 1] != '/') + strbuf_addch(path, '/'); + + len = path->len; + while ((e = readdir(dir)) != NULL) { + struct stat st; + if (is_dot_or_dotdot(e->d_name)) + continue; + + strbuf_setlen(path, len); + strbuf_addstr(path, e->d_name); + if (lstat(path->buf, &st)) + ; /* fall thru */ + else if (S_ISDIR(st.st_mode)) { + if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone)) + ret = 1; + if (gone) { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + string_list_append(&dels, quoted.buf); + } else + *dir_gone = 0; + continue; + } else { + res = dry_run ? 0 : unlink(path->buf); + if (!res) { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + string_list_append(&dels, quoted.buf); + } else { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + warning(_(msg_warn_remove_failed), quoted.buf); + *dir_gone = 0; + ret = 1; + } + continue; + } + + /* path too long, stat fails, or non-directory still exists */ + *dir_gone = 0; + ret = 1; + break; + } + closedir(dir); + + strbuf_setlen(path, original_len); + + if (*dir_gone) { + res = dry_run ? 0 : rmdir(path->buf); + if (!res) + *dir_gone = 1; + else { + quote_path_relative(path->buf, strlen(path->buf), "ed, prefix); + warning(_(msg_warn_remove_failed), quoted.buf); + *dir_gone = 0; + ret = 1; + } + } + + if (!*dir_gone && !quiet) { + for (i = 0; i < dels.nr; i++) + printf(dry_run ? _(msg_would_remove) : _(msg_remove), dels.items[i].string); + } + string_list_clear(&dels, 0); + return ret; +} + int cmd_clean(int argc, const char **argv, const char *prefix) { - int i; - int show_only = 0, remove_directories = 0, quiet = 0, ignored = 0; - int ignored_only = 0, config_set = 0, errors = 0; + int i, res; + int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0; + int ignored_only = 0, config_set = 0, errors = 0, gone = 1; int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT; struct strbuf directory = STRBUF_INIT; struct dir_struct dir; @@ -49,7 +157,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) char *seen = NULL; struct option options[] = { OPT__QUIET(&quiet, N_("do not print names of files removed")), - OPT__DRY_RUN(&show_only, N_("dry run")), + OPT__DRY_RUN(&dry_run, N_("dry run")), OPT__FORCE(&force, N_("force")), OPT_BOOLEAN('d', NULL, &remove_directories, N_("remove whole directories")), @@ -77,7 +185,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (ignored && ignored_only) die(_("-x and -X cannot be used together")); - if (!show_only && !force) { + if (!dry_run && !force) { if (config_set) die(_("clean.requireForce set to true and neither -n nor -f given; " "refusing to clean")); @@ -149,38 +257,26 @@ int cmd_clean(int argc, const char **argv, const char *prefix) if (S_ISDIR(st.st_mode)) { strbuf_addstr(&directory, ent->name); - qname = quote_path_relative(directory.buf, directory.len, &buf, prefix); - if (show_only && (remove_directories || - (matches == MATCHED_EXACTLY))) { - printf(_("Would remove %s\n"), qname); - } else if (remove_directories || - (matches == MATCHED_EXACTLY)) { - if (!quiet) - printf(_("Removing %s\n"), qname); - if (remove_dir_recursively(&directory, - rm_flags) != 0) { - warning(_("failed to remove %s"), qname); + if (remove_directories || (matches == MATCHED_EXACTLY)) { + if (remove_dirs(&directory, prefix, rm_flags, dry_run, quiet, &gone)) errors++; + if (gone && !quiet) { + qname = quote_path_relative(directory.buf, directory.len, &buf, prefix); + printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); } - } else if (show_only) { - printf(_("Would not remove %s\n"), qname); - } else { - printf(_("Not removing %s\n"), qname); } strbuf_reset(&directory); } else { if (pathspec && !matches) continue; - qname = quote_path_relative(ent->name, -1, &buf, prefix); - if (show_only) { - printf(_("Would remove %s\n"), qname); - continue; - } else if (!quiet) { - printf(_("Removing %s\n"), qname); - } - if (unlink(ent->name) != 0) { - warning(_("failed to remove %s"), qname); + res = dry_run ? 0 : unlink(ent->name); + if (res) { + qname = quote_path_relative(ent->name, -1, &buf, prefix); + warning(_(msg_warn_remove_failed), qname); errors++; + } else if (!quiet) { + qname = quote_path_relative(ent->name, -1, &buf, prefix); + printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname); } } } diff --git a/builtin/clone.c b/builtin/clone.c index 8d23a62e8a..36ec99db3f 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -704,6 +704,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (option_origin) die(_("--bare and --origin %s options are incompatible."), option_origin); + if (real_git_dir) + die(_("--bare and --separate-git-dir are incompatible.")); option_no_checkout = 1; } diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 43d364b8d5..ef62124aa4 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1099,7 +1099,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha if (fix_thin_pack) { struct sha1file *f; unsigned char read_sha1[20], tail_sha1[20]; - char msg[48]; + struct strbuf msg = STRBUF_INIT; int nr_unresolved = nr_deltas - nr_resolved_deltas; int nr_objects_initial = nr_objects; if (nr_unresolved <= 0) @@ -1109,9 +1109,10 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha * sizeof(*objects)); f = sha1fd(output_fd, curr_pack); fix_unresolved_deltas(f, nr_unresolved); - sprintf(msg, _("completed with %d local objects"), - nr_objects - nr_objects_initial); - stop_progress_msg(&progress, msg); + strbuf_addf(&msg, _("completed with %d local objects"), + nr_objects - nr_objects_initial); + stop_progress_msg(&progress, msg.buf); + strbuf_release(&msg); sha1close(f, tail_sha1, 0); hashcpy(read_sha1, pack_sha1); fixup_pack_header_footer(output_fd, pack_sha1, diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index e0d0b7d28b..bc912e399e 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -245,7 +245,7 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3]) unsigned dirmask = 0, mask = 0; for (i = 0; i < 3; i++) { - mask |= (1 << 1); + mask |= (1 << i); if (n[i].mode && S_ISDIR(n[i].mode)) dirmask |= (1 << i); } diff --git a/bundle.c b/bundle.c index 8d12816b9d..6210a6be89 100644 --- a/bundle.c +++ b/bundle.c @@ -183,17 +183,17 @@ int verify_bundle(struct bundle_header *header, int verbose) struct ref_list *r; r = &header->references; - printf_ln(Q_("The bundle contains %d ref", - "The bundle contains %d refs", + printf_ln(Q_("The bundle contains this ref:", + "The bundle contains these %d refs:", r->nr), r->nr); list_refs(r, 0, NULL); + r = &header->prerequisites; if (!r->nr) { printf_ln(_("The bundle records a complete history.")); } else { - r = &header->prerequisites; - printf_ln(Q_("The bundle requires this ref", - "The bundle requires these %d refs", + printf_ln(Q_("The bundle requires this ref:", + "The bundle requires these %d refs:", r->nr), r->nr); list_refs(r, 0, NULL); diff --git a/combine-diff.c b/combine-diff.c index bb1cc96c4e..7f6187f9cd 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -982,14 +982,10 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, free(sline); } -#define COLONS "::::::::::::::::::::::::::::::::" - static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct rev_info *rev) { struct diff_options *opt = &rev->diffopt; - int i, offset; - const char *prefix; - int line_termination, inter_name_termination; + int line_termination, inter_name_termination, i; line_termination = opt->line_termination; inter_name_termination = '\t'; @@ -1000,17 +996,14 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re show_log(rev); if (opt->output_format & DIFF_FORMAT_RAW) { - offset = strlen(COLONS) - num_parent; - if (offset < 0) - offset = 0; - prefix = COLONS + offset; + /* As many colons as there are parents */ + for (i = 0; i < num_parent; i++) + putchar(':'); /* Show the modes */ - for (i = 0; i < num_parent; i++) { - printf("%s%06o", prefix, p->parent[i].mode); - prefix = " "; - } - printf("%s%06o", prefix, p->mode); + for (i = 0; i < num_parent; i++) + printf("%06o ", p->parent[i].mode); + printf("%06o", p->mode); /* Show sha1's */ for (i = 0; i < num_parent; i++) diff --git a/daemon.c b/daemon.c index 4602b46a5c..df8c0ab058 100644 --- a/daemon.c +++ b/daemon.c @@ -9,10 +9,6 @@ #define HOST_NAME_MAX 256 #endif -#ifndef NI_MAXSERV -#define NI_MAXSERV 32 -#endif - #ifdef NO_INITGROUPS #define initgroups(x, y) (0) /* nothing */ #endif diff --git a/git-compat-util.h b/git-compat-util.h index 590d5d3188..9c01e9bc2e 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -209,6 +209,17 @@ extern char *gitbasename(char *); #include #endif +/* On most systems would have given us this, but + * not on some systems (e.g. z/OS). + */ +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + /* On most systems would have given us this, but * not on some systems (e.g. GNU/Hurd). */ diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 0a31ebd820..344f1206d1 100755 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -26,6 +26,7 @@ use IO::Pipe; use POSIX qw(strftime tzset dup2 ENOENT); use IPC::Open2; +use Git qw(get_tz_offset); $SIG{'PIPE'}="IGNORE"; set_timezone('UTC'); @@ -864,7 +865,9 @@ sub commit { } set_timezone($author_tz); - my $commit_date = strftime("%s %z", localtime($date)); + # $date is in the seconds since epoch format + my $tz_offset = get_tz_offset($date); + my $commit_date = "$date $tz_offset"; set_timezone('UTC'); $ENV{GIT_AUTHOR_NAME} = $author_name; $ENV{GIT_AUTHOR_EMAIL} = $author_email; diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index 3d0fe0cd93..b00ed95dba 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -40,7 +40,7 @@ launch_merge_tool () { # the user with the real $MERGED name before launching $merge_tool. if should_prompt then - printf "\nViewing: '$MERGED'\n" + printf "\nViewing: '%s'\n" "$MERGED" if use_ext_cmd then printf "Launch '%s' [Y/n]: " \ diff --git a/git-mergetool.sh b/git-mergetool.sh index c50e18a899..012afa5549 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -440,7 +440,7 @@ then fi printf "Merging:\n" -printf "$files\n" +printf "%s\n" "$files" IFS=' ' diff --git a/git.c b/git.c index d33f9b32a2..c598dc6367 100644 --- a/git.c +++ b/git.c @@ -6,10 +6,10 @@ #include "run-command.h" const char git_usage_string[] = - "git [--version] [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" + "git [--version] [--help] [-c name=value]\n" + " [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" " [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n" " [--git-dir=] [--work-tree=] [--namespace=]\n" - " [-c name=value] [--help]\n" " []"; const char git_more_info_string[] = @@ -536,7 +536,7 @@ int main(int argc, const char **argv) commit_pager_choice(); printf("usage: %s\n\n", git_usage_string); list_common_cmds_help(); - printf("\n%s\n", git_more_info_string); + printf("\n%s\n", _(git_more_info_string)); exit(1); } cmd = argv[0]; diff --git a/gitweb/README b/gitweb/README index 6da4778b73..471dcfb691 100644 --- a/gitweb/README +++ b/gitweb/README @@ -1,9 +1,6 @@ GIT web Interface ================= -The one working on: - http://git.kernel.org/ - From the git version 1.4.0 gitweb is bundled with git. diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index c6bafe6ead..1309196d27 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -2068,7 +2068,7 @@ sub picon_url { if (!$avatar_cache{$email}) { my ($user, $domain) = split('@', $email); $avatar_cache{$email} = - "http://www.cs.indiana.edu/cgi-pub/kinzler/piconsearch.cgi/" . + "//www.cs.indiana.edu/cgi-pub/kinzler/piconsearch.cgi/" . "$domain/$user/" . "users+domains+unknown/up/single"; } @@ -2083,7 +2083,7 @@ sub gravatar_url { my $email = lc shift; my $size = shift; $avatar_cache{$email} ||= - "http://www.gravatar.com/avatar/" . + "//www.gravatar.com/avatar/" . Digest::MD5::md5_hex($email) . "?s="; return $avatar_cache{$email} . $size; } diff --git a/http-push.c b/http-push.c index 8701c1215d..ba45b7b501 100644 --- a/http-push.c +++ b/http-push.c @@ -1560,7 +1560,7 @@ static int remote_exists(const char *path) sprintf(url, "%s%s", repo->url, path); - switch (http_get_strbuf(url, NULL, 0)) { + switch (http_get_strbuf(url, NULL, NULL, 0)) { case HTTP_OK: ret = 1; break; @@ -1584,7 +1584,7 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1) url = xmalloc(strlen(repo->url) + strlen(path) + 1); sprintf(url, "%s%s", repo->url, path); - if (http_get_strbuf(url, &buffer, 0) != HTTP_OK) + if (http_get_strbuf(url, NULL, &buffer, 0) != HTTP_OK) die("Couldn't get %s for remote symref\n%s", url, curl_errorstr); free(url); diff --git a/http.c b/http.c index 44f35256e4..d9d1aad3be 100644 --- a/http.c +++ b/http.c @@ -788,7 +788,8 @@ int handle_curl_result(struct slot_results *results) #define HTTP_REQUEST_STRBUF 0 #define HTTP_REQUEST_FILE 1 -static int http_request(const char *url, void *result, int target, int options) +static int http_request(const char *url, struct strbuf *type, + void *result, int target, int options) { struct active_request_slot *slot; struct slot_results results; @@ -838,24 +839,37 @@ static int http_request(const char *url, void *result, int target, int options) ret = HTTP_START_FAILED; } + if (type) { + char *t; + strbuf_reset(type); + curl_easy_getinfo(slot->curl, CURLINFO_CONTENT_TYPE, &t); + if (t) + strbuf_addstr(type, t); + } + curl_slist_free_all(headers); strbuf_release(&buf); return ret; } -static int http_request_reauth(const char *url, void *result, int target, +static int http_request_reauth(const char *url, + struct strbuf *type, + void *result, int target, int options) { - int ret = http_request(url, result, target, options); + int ret = http_request(url, type, result, target, options); if (ret != HTTP_REAUTH) return ret; - return http_request(url, result, target, options); + return http_request(url, type, result, target, options); } -int http_get_strbuf(const char *url, struct strbuf *result, int options) +int http_get_strbuf(const char *url, + struct strbuf *type, + struct strbuf *result, int options) { - return http_request_reauth(url, result, HTTP_REQUEST_STRBUF, options); + return http_request_reauth(url, type, result, + HTTP_REQUEST_STRBUF, options); } /* @@ -878,7 +892,7 @@ static int http_get_file(const char *url, const char *filename, int options) goto cleanup; } - ret = http_request_reauth(url, result, HTTP_REQUEST_FILE, options); + ret = http_request_reauth(url, NULL, result, HTTP_REQUEST_FILE, options); fclose(result); if ((ret == HTTP_OK) && move_temp_to_file(tmpfile.buf, filename)) @@ -904,7 +918,7 @@ int http_fetch_ref(const char *base, struct ref *ref) int ret = -1; url = quote_ref_url(base, ref->name); - if (http_get_strbuf(url, &buffer, HTTP_NO_CACHE) == HTTP_OK) { + if (http_get_strbuf(url, NULL, &buffer, HTTP_NO_CACHE) == HTTP_OK) { strbuf_rtrim(&buffer); if (buffer.len == 40) ret = get_sha1_hex(buffer.buf, ref->old_sha1); @@ -997,7 +1011,7 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head) strbuf_addstr(&buf, "objects/info/packs"); url = strbuf_detach(&buf, NULL); - ret = http_get_strbuf(url, &buf, HTTP_NO_CACHE); + ret = http_get_strbuf(url, NULL, &buf, HTTP_NO_CACHE); if (ret != HTTP_OK) goto cleanup; diff --git a/http.h b/http.h index 0a80d303e3..25d1931398 100644 --- a/http.h +++ b/http.h @@ -132,7 +132,7 @@ extern char *get_remote_object_url(const char *url, const char *hex, * * If the result pointer is NULL, a HTTP HEAD request is made instead of GET. */ -int http_get_strbuf(const char *url, struct strbuf *result, int options); +int http_get_strbuf(const char *url, struct strbuf *content_type, struct strbuf *result, int options); /* * Prints an error message using error() containing url and curl_errorstr, diff --git a/imap-send.c b/imap-send.c index ef500111ec..49ba841cba 100644 --- a/imap-send.c +++ b/imap-send.c @@ -370,6 +370,17 @@ static int ssl_socket_connect(struct imap_socket *sock, int use_tls_only, int ve return -1; } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + /* + * SNI (RFC4366) + * OpenSSL does not document this function, but the implementation + * returns 1 on success, 0 on failure after calling SSLerr(). + */ + ret = SSL_set_tlsext_host_name(sock->ssl, server.host); + if (ret != 1) + warning("SSL_set_tlsext_host_name(%s) failed.", server.host); +#endif + ret = SSL_connect(sock->ssl); if (ret <= 0) { socket_perror("SSL_connect", sock, ret); diff --git a/mergetools/p4merge b/mergetools/p4merge index 295361a8aa..8a36916567 100644 --- a/mergetools/p4merge +++ b/mergetools/p4merge @@ -1,29 +1,21 @@ diff_cmd () { + empty_file= + # p4merge does not like /dev/null - rm_local= - rm_remote= if test "/dev/null" = "$LOCAL" then - LOCAL="./p4merge-dev-null.LOCAL.$$" - >"$LOCAL" - rm_local=true + LOCAL="$(create_empty_file)" fi if test "/dev/null" = "$REMOTE" then - REMOTE="./p4merge-dev-null.REMOTE.$$" - >"$REMOTE" - rm_remote=true + REMOTE="$(create_empty_file)" fi "$merge_tool_path" "$LOCAL" "$REMOTE" - if test -n "$rm_local" - then - rm -f "$LOCAL" - fi - if test -n "$rm_remote" + if test -n "$empty_file" then - rm -f "$REMOTE" + rm -f "$empty_file" fi } @@ -33,3 +25,10 @@ merge_cmd () { "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED" check_unchanged } + +create_empty_file () { + empty_file="${TMPDIR:-/tmp}/git-difftool-p4merge-empty-file.$$" + >"$empty_file" + + printf "%s" "$empty_file" +} diff --git a/parse-options.c b/parse-options.c index c1c66bd408..7ca8f2caef 100644 --- a/parse-options.c +++ b/parse-options.c @@ -3,6 +3,7 @@ #include "cache.h" #include "commit.h" #include "color.h" +#include "utf8.h" static int parse_options_usage(struct parse_opt_ctx_t *ctx, const char * const *usagestr, @@ -470,8 +471,11 @@ int parse_options(int argc, const char **argv, const char *prefix, default: /* PARSE_OPT_UNKNOWN */ if (ctx.argv[0][1] == '-') { error("unknown option `%s'", ctx.argv[0] + 2); - } else { + } else if (isascii(*ctx.opt)) { error("unknown switch `%c'", *ctx.opt); + } else { + error("unknown non-ascii option in string: `%s'", + ctx.argv[0]); } usage_with_options(usagestr, options); } @@ -491,7 +495,7 @@ static int usage_argh(const struct option *opts, FILE *outfile) s = literal ? "[%s]" : "[<%s>]"; else s = literal ? " %s" : " <%s>"; - return fprintf(outfile, s, opts->argh ? _(opts->argh) : _("...")); + return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("...")); } #define USAGE_OPTS_WIDTH 24 @@ -550,7 +554,7 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx, if (opts->long_name) pos += fprintf(outfile, "--%s", opts->long_name); if (opts->type == OPTION_NUMBER) - pos += fprintf(outfile, "-NUM"); + pos += utf8_fprintf(outfile, _("-NUM")); if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !(opts->flags & PARSE_OPT_NOARG)) diff --git a/perl/Git.pm b/perl/Git.pm index 931047c51d..57a17160f9 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -59,6 +59,7 @@ =head1 SYNOPSIS command_bidi_pipe command_close_bidi_pipe version exec_path html_path hash_object git_cmd_try remote_refs prompt + get_tz_offset temp_acquire temp_release temp_reset temp_path); @@ -102,6 +103,7 @@ =head1 DESCRIPTION use Cwd qw(abs_path cwd); use IPC::Open2 qw(open2); use Fcntl qw(SEEK_SET SEEK_CUR); +use Time::Local qw(timegm); } @@ -511,6 +513,27 @@ sub version { sub html_path { command_oneline('--html-path') } + +=item get_tz_offset ( TIME ) + +Return the time zone offset from GMT in the form +/-HHMM where HH is +the number of hours from GMT and MM is the number of minutes. This is +the equivalent of what strftime("%z", ...) would provide on a GNU +platform. + +If TIME is not supplied, the current local time is used. + +=cut + +sub get_tz_offset { + # some systmes don't handle or mishandle %z, so be creative. + my $t = shift || time; + my $gm = timegm(localtime($t)); + my $sign = qw( + + - )[ $gm <=> $t ]; + return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]); +} + + =item prompt ( PROMPT , ISPASSWORD ) Query user C and return answer from user. @@ -942,20 +965,22 @@ sub cat_blob { my $size = $1; my $blob; - my $bytesRead = 0; + my $bytesLeft = $size; while (1) { - my $bytesLeft = $size - $bytesRead; last unless $bytesLeft; my $bytesToRead = $bytesLeft < 1024 ? $bytesLeft : 1024; - my $read = read($in, $blob, $bytesToRead, $bytesRead); + my $read = read($in, $blob, $bytesToRead); unless (defined($read)) { $self->_close_cat_blob(); throw Error::Simple("in pipe went bad"); } - - $bytesRead += $read; + unless (print $fh $blob) { + $self->_close_cat_blob(); + throw Error::Simple("couldn't write to passed in filehandle"); + } + $bytesLeft -= $read; } # Skip past the trailing newline. @@ -970,11 +995,6 @@ sub cat_blob { throw Error::Simple("didn't find newline after blob"); } - unless (print $fh $blob) { - $self->_close_cat_blob(); - throw Error::Simple("couldn't write to passed in filehandle"); - } - return $size; } diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm index 59215fa86e..8c84560a49 100644 --- a/perl/Git/SVN.pm +++ b/perl/Git/SVN.pm @@ -11,7 +11,6 @@ package Git::SVN; use File::Path qw/mkpath/; use File::Copy qw/copy/; use IPC::Open3; -use Time::Local; use Memoize; # core since 5.8.0, Jul 2002 use Memoize::Storable; use POSIX qw(:signal_h); @@ -22,6 +21,7 @@ package Git::SVN; command_noisy command_output_pipe command_close_pipe + get_tz_offset ); use Git::SVN::Utils qw( fatal @@ -1311,14 +1311,6 @@ sub get_untracked { \@out; } -sub get_tz { - # some systmes don't handle or mishandle %z, so be creative. - my $t = shift || time; - my $gm = timelocal(gmtime($t)); - my $sign = qw( + + - )[ $t <=> $gm ]; - return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]); -} - # parse_svn_date(DATE) # -------------------- # Given a date (in UTC) from Subversion, return a string in the format @@ -1351,7 +1343,7 @@ sub parse_svn_date { delete $ENV{TZ}; } - my $our_TZ = get_tz(); + my $our_TZ = get_tz_offset(); # This converts $epoch_in_UTC into our local timezone. my ($sec, $min, $hour, $mday, $mon, $year, diff --git a/perl/Git/SVN/Log.pm b/perl/Git/SVN/Log.pm index 3cc1c6f081..3f8350a57d 100644 --- a/perl/Git/SVN/Log.pm +++ b/perl/Git/SVN/Log.pm @@ -2,7 +2,11 @@ package Git::SVN::Log; use strict; use warnings; use Git::SVN::Utils qw(fatal); -use Git qw(command command_oneline command_output_pipe command_close_pipe); +use Git qw(command + command_oneline + command_output_pipe + command_close_pipe + get_tz_offset); use POSIX qw/strftime/; use constant commit_log_separator => ('-' x 72) . "\n"; use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline @@ -119,7 +123,7 @@ sub run_pager { sub format_svn_date { my $t = shift || time; require Git::SVN; - my $gmoff = Git::SVN::get_tz($t); + my $gmoff = get_tz_offset($t); return strftime("%Y-%m-%d %H:%M:%S $gmoff (%a, %d %b %Y)", localtime($t)); } diff --git a/read-cache.c b/read-cache.c index fda78bc353..5cddbc325f 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1256,7 +1256,7 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size) if (hdr->hdr_signature != htonl(CACHE_SIGNATURE)) return error("bad signature"); hdr_version = ntohl(hdr->hdr_version); - if (hdr_version < 2 || 4 < hdr_version) + if (hdr_version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < hdr_version) return error("bad index version %d", hdr_version); git_SHA1_Init(&c); git_SHA1_Update(&c, hdr, size - 20); diff --git a/remote-curl.c b/remote-curl.c index 9a8b123507..933c69ac26 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -92,6 +92,8 @@ static void free_discovery(struct discovery *d) static struct discovery* discover_refs(const char *service) { + struct strbuf exp = STRBUF_INIT; + struct strbuf type = STRBUF_INIT; struct strbuf buffer = STRBUF_INIT; struct discovery *last = last_discovery; char *refs_url; @@ -113,7 +115,7 @@ static struct discovery* discover_refs(const char *service) } refs_url = strbuf_detach(&buffer, NULL); - http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE); + http_ret = http_get_strbuf(refs_url, &type, &buffer, HTTP_NO_CACHE); switch (http_ret) { case HTTP_OK: break; @@ -132,17 +134,20 @@ static struct discovery* discover_refs(const char *service) last->buf_alloc = strbuf_detach(&buffer, &last->len); last->buf = last->buf_alloc; - if (maybe_smart && 5 <= last->len && last->buf[4] == '#') { - /* smart HTTP response; validate that the service + strbuf_addf(&exp, "application/x-%s-advertisement", service); + if (maybe_smart && + (5 <= last->len && last->buf[4] == '#') && + !strbuf_cmp(&exp, &type)) { + /* + * smart HTTP response; validate that the service * pkt-line matches our request. */ - struct strbuf exp = STRBUF_INIT; - if (packet_get_line(&buffer, &last->buf, &last->len) <= 0) die("%s has invalid packet header", refs_url); if (buffer.len && buffer.buf[buffer.len - 1] == '\n') strbuf_setlen(&buffer, buffer.len - 1); + strbuf_reset(&exp); strbuf_addf(&exp, "# service=%s", service); if (strbuf_cmp(&exp, &buffer)) die("invalid server response; got '%s'", buffer.buf); @@ -160,6 +165,8 @@ static struct discovery* discover_refs(const char *service) } free(refs_url); + strbuf_release(&exp); + strbuf_release(&type); strbuf_release(&buffer); last_discovery = last; return last; diff --git a/setup.c b/setup.c index f108c4b990..1b120175f2 100644 --- a/setup.c +++ b/setup.c @@ -624,22 +624,32 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ /* * A "string_list_each_func_t" function that canonicalizes an entry * from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or - * discards it if unusable. + * discards it if unusable. The presence of an empty entry in + * GIT_CEILING_DIRECTORIES turns off canonicalization for all + * subsequent entries. */ static int canonicalize_ceiling_entry(struct string_list_item *item, - void *unused) + void *cb_data) { + int *empty_entry_found = cb_data; char *ceil = item->string; - const char *real_path; - if (!*ceil || !is_absolute_path(ceil)) + if (!*ceil) { + *empty_entry_found = 1; return 0; - real_path = real_path_if_valid(ceil); - if (!real_path) + } else if (!is_absolute_path(ceil)) { return 0; - free(item->string); - item->string = xstrdup(real_path); - return 1; + } else if (*empty_entry_found) { + /* Keep entry but do not canonicalize it */ + return 1; + } else { + const char *real_path = real_path_if_valid(ceil); + if (!real_path) + return 0; + free(item->string); + item->string = xstrdup(real_path); + return 1; + } } /* @@ -679,9 +689,11 @@ static const char *setup_git_directory_gently_1(int *nongit_ok) return setup_explicit_git_dir(gitdirenv, cwd, len, nongit_ok); if (env_ceiling_dirs) { + int empty_entry_found = 0; + string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); filter_string_list(&ceiling_dirs, 0, - canonicalize_ceiling_entry, NULL); + canonicalize_ceiling_entry, &empty_entry_found); ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs); string_list_clear(&ceiling_dirs, 0); } diff --git a/sha1_name.c b/sha1_name.c index 95003c77ea..c50630a3ea 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1137,7 +1137,8 @@ int get_sha1_blob(const char *name, unsigned char *sha1) static void diagnose_invalid_sha1_path(const char *prefix, const char *filename, const unsigned char *tree_sha1, - const char *object_name) + const char *object_name, + int object_name_len) { struct stat st; unsigned char sha1[20]; @@ -1147,8 +1148,8 @@ static void diagnose_invalid_sha1_path(const char *prefix, prefix = ""; if (!lstat(filename, &st)) - die("Path '%s' exists on disk, but not in '%s'.", - filename, object_name); + die("Path '%s' exists on disk, but not in '%.*s'.", + filename, object_name_len, object_name); if (errno == ENOENT || errno == ENOTDIR) { char *fullname = xmalloc(strlen(filename) + strlen(prefix) + 1); @@ -1158,16 +1159,16 @@ static void diagnose_invalid_sha1_path(const char *prefix, if (!get_tree_entry(tree_sha1, fullname, sha1, &mode)) { die("Path '%s' exists, but not '%s'.\n" - "Did you mean '%s:%s' aka '%s:./%s'?", + "Did you mean '%.*s:%s' aka '%.*s:./%s'?", fullname, filename, - object_name, + object_name_len, object_name, fullname, - object_name, + object_name_len, object_name, filename); } - die("Path '%s' does not exist in '%s'", - filename, object_name); + die("Path '%s' does not exist in '%.*s'", + filename, object_name_len, object_name); } } @@ -1332,13 +1333,8 @@ static int get_sha1_with_context_1(const char *name, } if (*cp == ':') { unsigned char tree_sha1[20]; - char *object_name = NULL; - if (only_to_die) { - object_name = xmalloc(cp-name+1); - strncpy(object_name, name, cp-name); - object_name[cp-name] = '\0'; - } - if (!get_sha1_1(name, cp-name, tree_sha1, GET_SHA1_TREEISH)) { + int len = cp - name; + if (!get_sha1_1(name, len, tree_sha1, GET_SHA1_TREEISH)) { const char *filename = cp+1; char *new_filename = NULL; @@ -1348,8 +1344,8 @@ static int get_sha1_with_context_1(const char *name, ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode); if (ret && only_to_die) { diagnose_invalid_sha1_path(prefix, filename, - tree_sha1, object_name); - free(object_name); + tree_sha1, + name, len); } hashcpy(oc->tree, tree_sha1); strncpy(oc->path, filename, @@ -1360,7 +1356,7 @@ static int get_sha1_with_context_1(const char *name, return ret; } else { if (only_to_die) - die("Invalid object name '%s'.", object_name); + die("Invalid object name '%.*s'.", len, name); } } return ret; diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 02f442bfad..895b9258b0 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -80,6 +80,7 @@ fi prepare_httpd() { mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" + cp "$TEST_PATH"/broken-smart-http.sh "$HTTPD_ROOT_PATH" ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index fe76e84b74..938b4cf803 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -62,9 +62,13 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_COMMITTER_EMAIL custom@example.com ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 +ScriptAlias /broken_smart/ broken-smart-http.sh/ Options FollowSymlinks + + Options ExecCGI + Options ExecCGI diff --git a/t/lib-httpd/broken-smart-http.sh b/t/lib-httpd/broken-smart-http.sh new file mode 100755 index 0000000000..f7ebfffa80 --- /dev/null +++ b/t/lib-httpd/broken-smart-http.sh @@ -0,0 +1,11 @@ +#!/bin/sh +printf "Content-Type: text/%s\n" "html" +echo +printf "%s\n" "001e# service=git-upload-pack" +printf "%s" "0000" +printf "%s%c%s%s\n" \ + "00a58681d9f286a48b08f37b3a095330da16689e3693 HEAD" \ + 0 \ + " include-tag multi_ack_detailed multi_ack ofs-delta" \ + " side-band side-band-64k thin-pack no-progress shallow no-done " +printf "%s" "0000" diff --git a/t/perf/README b/t/perf/README index b2dbad4d50..c552f561bf 100644 --- a/t/perf/README +++ b/t/perf/README @@ -56,7 +56,7 @@ You can set the following variables (also in your config.mak): GIT_PERF_REPEAT_COUNT Number of times a test should be repeated for best-of-N - measurements. Defaults to 5. + measurements. Defaults to 3. GIT_PERF_MAKE_OPTS Options to use when automatically building a git tree for diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 807b8b88e2..1035a14b37 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -198,7 +198,8 @@ test_expect_success 'root subdir attribute test' ' test_expect_success 'negative patterns' ' echo "!f test=bar" >.gitattributes && - test_must_fail git check-attr test -- f + git check-attr test -- '"'"'!f'"'"' 2>errors && + test_i18ngrep "Negative patterns are ignored" errors ' test_expect_success 'patterns starting with exclamation' ' diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh index cce87a5ab5..3d51615e42 100755 --- a/t/t1504-ceiling-dirs.sh +++ b/t/t1504-ceiling-dirs.sh @@ -44,6 +44,10 @@ test_prefix ceil_at_sub "" GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" test_prefix ceil_at_sub_slash "" +if test_have_prereq SYMLINKS +then + ln -s sub top +fi mkdir -p sub/dir || exit 1 cd sub/dir || exit 1 @@ -68,6 +72,19 @@ test_fail subdir_ceil_at_sub GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/" test_fail subdir_ceil_at_sub_slash +if test_have_prereq SYMLINKS +then + GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top" + test_fail subdir_ceil_at_top + GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top/" + test_fail subdir_ceil_at_top_slash + + GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top" + test_prefix subdir_ceil_at_top_no_resolve "sub/dir/" + GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top/" + test_prefix subdir_ceil_at_top_slash_no_resolve "sub/dir/" +fi + GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir" test_prefix subdir_ceil_at_subdir "sub/dir/" diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index d6e576192f..b27a7209f7 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -54,6 +54,10 @@ test_expect_success 'my-side@{upstream} resolves to correct full name' ' test refs/remotes/origin/side = "$(full_name my-side@{u})" ' +test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' ' + test_must_fail full_name refs/heads/my-side@{upstream} +' + test_expect_success 'my-side@{u} resolves to correct commit' ' git checkout side && test_commit 5 && diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index 40277c77aa..614425adac 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -89,4 +89,28 @@ test_expect_success 'diagnose truncated file' ' grep "diff --cc file" out ' +test_expect_success 'setup for --cc --raw' ' + blob=$(echo file | git hash-object --stdin -w) && + base_tree=$(echo "100644 blob $blob file" | git mktree) && + trees= && + for i in `test_seq 1 40` + do + blob=$(echo file$i | git hash-object --stdin -w) && + trees="$trees$(echo "100644 blob $blob file" | git mktree)$LF" + done +' + +test_expect_success 'check --cc --raw with four trees' ' + four_trees=$(echo "$trees" | sed -e 4q) && + git diff --cc --raw $four_trees $base_tree >out && + # Check for four leading colons in the output: + grep "^::::[^:]" out +' + +test_expect_success 'check --cc --raw with forty trees' ' + git diff --cc --raw $trees $base_tree >out && + # Check for forty leading colons in the output: + grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out +' + test_done diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index c5cd2e348c..47eb76921d 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -157,6 +157,11 @@ test_expect_success 'GIT_SMART_HTTP can disable smart http' ' test_must_fail git fetch) ' +test_expect_success 'invalid Content-Type rejected' ' + test_must_fail git clone $HTTPD_URL/broken_smart/repo.git 2>actual + grep "not valid:" actual +' + test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index b3f6eb9c68..95d651080f 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -5,7 +5,7 @@ # Grenoble INP Ensimag # -test_description='git status advices' +test_description='git status advice' . ./test-lib.sh diff --git a/utf8.c b/utf8.c index a4ee6650ef..1087870c51 100644 --- a/utf8.c +++ b/utf8.c @@ -429,6 +429,27 @@ int same_encoding(const char *src, const char *dst) return !strcasecmp(src, dst); } +/* + * Wrapper for fprintf and returns the total number of columns required + * for the printed string, assuming that the string is utf8. + */ +int utf8_fprintf(FILE *stream, const char *format, ...) +{ + struct strbuf buf = STRBUF_INIT; + va_list arg; + int columns; + + va_start(arg, format); + strbuf_vaddf(&buf, format, arg); + va_end(arg); + + columns = fputs(buf.buf, stream); + if (0 <= columns) /* keep the error from the I/O */ + columns = utf8_strwidth(buf.buf); + strbuf_release(&buf); + return columns; +} + /* * Given a buffer and its encoding, return it re-encoded * with iconv. If the conversion fails, returns NULL. diff --git a/utf8.h b/utf8.h index a214238bdd..501b2bd9c4 100644 --- a/utf8.h +++ b/utf8.h @@ -8,6 +8,7 @@ int utf8_strwidth(const char *string); int is_utf8(const char *text); int is_encoding_utf8(const char *name); int same_encoding(const char *, const char *); +int utf8_fprintf(FILE *, const char *, ...); void strbuf_add_wrapped_text(struct strbuf *buf, const char *text, int indent, int indent2, int width);