#
ifndef ASCIIDOC7
-ASCIIDOC_EXTRA += -a asciidoc7compatible -a no-inline-literal
+ASCIIDOC_EXTRA += -a asciidoc7compatible
endif
ifdef DOCBOOK_XSL_172
ASCIIDOC_EXTRA += -a git-asciidoc-no-roff
* HTTP transport that requires authentication did not work correctly when
multiple connections are used simultaneously.
+ * Minor memory leak during unpack_trees (hence "merge" and "checkout"
+ to check out another branch) has been plugged.
+
* In the older days, the header "Conflicts:" in "cherry-pick" and "merge"
was separated by a blank line from the list of paths that follow for
readability, but when "merge" was rewritten in C, we lost it by
be both revision name and a pathname, even though $name can never be a
path in the context of the command.
+ * The "include.path" facility in the configuration mechanism added in
+ 1.7.10 forgot to interpret "~/path" and "~user/path" as it should.
+
* "git config --rename-section" to rename an existing section into a
bogus one did not check the new name.
* The report from "git fetch" said "new branch" even for a non branch
ref.
+ * The http-backend (the server side of the smart http transfer) used
+ to overwrite GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL with the
+ value obtained from REMOTE_USER unconditionally, making it
+ impossible for the server side site-specific customization to use
+ different identity sources to affect the names logged. It now uses
+ REMOTE_USER only as a fallback value.
+
+ * "log --graph" was not very friendly with "--stat" option and its
+ output had line breaks at wrong places.
+
* Octopus merge strategy did not reduce heads that are recorded in the
final commit correctly.
+ * "git push" over smart-http lost progress output a few releases ago;
+ this release resurrects it.
+
+ * The error and advice messages given by "git push" when it fails due
+ to non-ff were not very helpful to new users; it has been broken
+ into three cases, and each is given a separate advice message.
+
+ * The insn sheet given by "rebase -i" did not make it clear that the
+ insn lines can be re-ordered to affect the order of the commits in
+ the resulting history.
+
+ * "git repack" used to write out unreachable objects as loose objects
+ when repacking, even if such loose objects will immediately pruned
+ due to its age.
+
+ * A contrib script "rerere-train" did not work out of the box unless
+ user futzed with her $PATH.
+
+ * "git rev-parse --show-prefix" used to emit nothing when run at the
+ top-level of the working tree, but now it gives a blank line.
+
* The i18n of error message "git stash save" was not properly done.
+ * "git submodule" used a sed script that some platforms mishandled.
+
* When using a Perl script on a system where "perl" found on user's
$PATH could be ancient or otherwise broken, we allow builders to
specify the path to a good copy of Perl with $PERL_PATH. The
--- /dev/null
+Git v1.7.10.3 Release Notes
+===========================
+
+Fixes since v1.7.10.2
+---------------------
+
+ * Running "git checkout" on an unborn branch used to corrupt HEAD.
+
+ * When checking out another commit from an already detached state, we
+ used to report all commits that are not reachable from any of the
+ refs as lossage, but some of them might be reachable from the new
+ HEAD, and there is no need to warn about them.
+
+ * Some time ago, "git clone" lost the progress output for its
+ "checkout" phase; when run without any "--quiet" option, it should
+ give progress to the lengthy operation.
+
+ * "log -z --pretty=tformat:..." did not terminate each record with
+ NUL. The fix is not entirely correct when the output also asks for
+ --patch and/or --stat, though.
+
+ * The DWIM behaviour for "log --pretty=format:%gd -g" was somewhat
+ broken and gave undue precedence to configured log.date, causing
+ "git stash list" to show "stash@{time stamp string}".
+
+Also contains minor fixes and documentation updates.
found at the location of the include directive. If the value of the
`include.path` variable is a relative path, the path is considered to be
relative to the configuration file in which the include directive was
-found. See below for examples.
+found. The value of `include.path` is subject to tilde expansion: `{tilde}/`
+is expanded to the value of `$HOME`, and `{tilde}user/` to the specified
+user's home directory. See below for examples.
Example
~~~~~~~
[include]
path = /path/to/foo.inc ; include by absolute path
path = foo ; expand "foo" relative to the current file
+ path = ~/foo ; expand "foo" in your $HOME directory
Variables
~~~~~~~~~
+
--
pushNonFastForward::
- Advice shown when linkgit:git-push[1] refuses
- non-fast-forward refs.
+ Set this variable to 'false' if you want to disable
+ 'pushNonFFCurrent', 'pushNonFFDefault', and
+ 'pushNonFFMatching' simultaneously.
+ pushNonFFCurrent::
+ Advice shown when linkgit:git-push[1] fails due to a
+ non-fast-forward update to the current branch.
+ pushNonFFDefault::
+ Advice to set 'push.default' to 'upstream' or 'current'
+ when you ran linkgit:git-push[1] and pushed 'matching
+ refs' by default (i.e. you did not provide an explicit
+ refspec, and no 'push.default' configuration was set)
+ and it resulted in a non-fast-forward error.
+ pushNonFFMatching::
+ Advice shown when you ran linkgit:git-push[1] and pushed
+ 'matching refs' explicitly (i.e. you used ':', or
+ specified a refspec that isn't your current branch) and
+ it resulted in a non-fast-forward error.
statusHints::
Directions on how to stage/unstage/add shown in the
output of linkgit:git-status[1] and the template shown
core.excludesfile::
In addition to '.gitignore' (per-directory) and
'.git/info/exclude', git looks into this file for patterns
- of files which are not meant to be tracked. "{tilde}/" is expanded
- to the value of `$HOME` and "{tilde}user/" to the specified user's
+ of files which are not meant to be tracked. "`~/`" is expanded
+ to the value of `$HOME` and "`~user/`" to the specified user's
home directory. See linkgit:gitignore[5].
core.askpass::
commit.template::
Specify a file to use as the template for new commit messages.
- "{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
+ "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the
specified user's home directory.
credential.helper::
a boolean value, or `shallow` or `deep`. `shallow` threading
makes every mail a reply to the head of the series,
where the head is chosen from the cover letter, the
- `\--in-reply-to`, and the first patch mail, in this order.
+ `--in-reply-to`, and the first patch mail, in this order.
`deep` threading makes every mail a reply to the previous one.
A true boolean value is the same as `shallow`, and a false
value disables threading.
interactive.singlekey::
In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
- Currently this is used by the `\--patch` mode of
+ Currently this is used by the `--patch` mode of
linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1],
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
setting is silently ignored if portable keystroke input
log.abbrevCommit::
If true, makes linkgit:git-log[1], linkgit:git-show[1], and
- linkgit:git-whatchanged[1] assume `\--abbrev-commit`. You may
- override this option with `\--no-abbrev-commit`.
+ linkgit:git-whatchanged[1] assume `--abbrev-commit`. You may
+ override this option with `--no-abbrev-commit`.
log.date::
Set the default date-time mode for the 'log' command.
Setting a value for log.date is similar to using 'git log''s
- `\--date` option. Possible values are `relative`, `local`,
+ `--date` option. Possible values are `relative`, `local`,
`default`, `iso`, `rfc`, and `short`; see linkgit:git-log[1]
for details.
and this config option ignored whenever the corresponding pack is
larger than 2 GB.
+
-If you have an old git that does not understand the version 2 `{asterisk}.idx` file,
+If you have an old git that does not understand the version 2 `*.idx` file,
cloning or fetching over a non native protocol (e.g. "http" and "rsync")
-that will copy both `{asterisk}.pack` file and corresponding `{asterisk}.idx` file from the
+that will copy both `*.pack` file and corresponding `*.idx` file from the
other side may give you a repository that cannot be accessed with your
-older version of git. If the `{asterisk}.pack` file is smaller than 2 GB, however,
+older version of git. If the `*.pack` file is smaller than 2 GB, however,
you can use linkgit:git-index-pack[1] on the *.pack file to regenerate
-the `{asterisk}.idx` file.
+the `*.idx` file.
pack.packSizeLimit::
The maximum size of a pack. This setting only affects
packing to a file when repacking, i.e. the git:// protocol
- is unaffected. It can be overridden by the `\--max-pack-size`
+ is unaffected. It can be overridden by the `--max-pack-size`
option of linkgit:git-repack[1]. The minimum size allowed is
limited to 1 MiB. The default is unlimited.
Common unit suffixes of 'k', 'm', or 'g' are
If the value is boolean, turns on or off pagination of the
output of a particular git subcommand when writing to a tty.
Otherwise, turns on pagination for the subcommand using the
- pager specified by the value of `pager.<cmd>`. If `\--paginate`
- or `\--no-pager` is specified on the command line, it takes
+ pager specified by the value of `pager.<cmd>`. If `--paginate`
+ or `--no-pager` is specified on the command line, it takes
precedence over this option. To disable pagination for all
commands, set `core.pager` or `GIT_PAGER` to `cat`.
Alias for a --pretty= format string, as specified in
linkgit:git-log[1]. Any aliases defined here can be used just
as the built-in pretty formats could. For example,
- running `git config pretty.changelog "format:{asterisk} %H %s"`
+ running `git config pretty.changelog "format:* %H %s"`
would cause the invocation `git log --pretty=changelog`
- to be equivalent to running `git log "--pretty=format:{asterisk} %H %s"`.
+ to be equivalent to running `git log "--pretty=format:* %H %s"`.
Note that an alias with the same name as a built-in format
will be silently ignored.
remote.<name>.mirror::
If true, pushing to this remote will automatically behave
- as if the `\--mirror` option was given on the command line.
+ as if the `--mirror` option was given on the command line.
remote.<name>.skipDefaultUpdate::
If true, this remote will be skipped by default when updating
from both files (hence two `-` removals from both file1 and
file2, plus `++` to mean one line that was added does not appear
in either file1 nor file2). Also eight other lines are the same
-from file1 but do not appear in file2 (hence prefixed with `{plus}`).
+from file1 but do not appear in file2 (hence prefixed with `+`).
When shown by `git diff-tree -c`, it compares the parents of a
merge commit with the merge result (i.e. file1..fileN are the
`--stat-name-width=<name-width>` and `--stat-count=<count>`.
--numstat::
- Similar to `\--stat`, but shows number of added and
+ Similar to `--stat`, but shows number of added and
deleted lines in decimal notation and pathname without
abbreviation, to make it more machine friendly. For
binary files, outputs two `-` instead of saying
<9> switch to the master branch.
<10> merge a topic branch into your master branch.
<11> review commit logs; other forms to limit output can be
-combined and include `\--max-count=10` (show 10 commits),
-`\--until=2005-12-10`, etc.
+combined and include `--max-count=10` (show 10 commits),
+`--until=2005-12-10`, etc.
<12> view only the changes that touch what's in `curses/`
directory, since `v2.43` tag.
Same as above, but the format is inferred from the output file.
-`git archive --format=tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz`::
+`git archive --format=tar --prefix=git-1.4.0/ v1.4.0^{tree} | gzip >git-1.4.0.tar.gz`::
Create a compressed tarball for v1.4.0 release, but without a
global extended pax header.
git log --diff-filter=A --pretty=short -- foo
and then annotate the change between the commit and its
-parents, using `commit{caret}!` notation:
+parents, using `commit^!` notation:
git blame -C -C -f $commit^! -- foo
A list of arguments, acceptable to 'git rev-parse' and
'git rev-list' (and containing a named ref, see SPECIFYING REFERENCES
below), that specifies the specific objects and references
- to transport. For example, `master{tilde}10..master` causes the
+ to transport. For example, `master~10..master` causes the
current master reference to be packaged along with all objects
added since its 10th ancestor commit. There is no explicit
limit to the number of references and objects that may be
'git bundle' will only package references that are shown by
'git show-ref': this includes heads, tags, and remote heads. References
-such as `master{tilde}1` cannot be packaged, but are perfectly suitable for
+such as `master~1` cannot be packaged, but are perfectly suitable for
defining the basis. More than one reference may be packaged, and more
than one basis can be specified. The objects packaged are those not
contained in the union of the given bases. Each basis can be
-specified explicitly (e.g. `^master{tilde}10`), or implicitly (e.g.
-`master{tilde}10..master`, `--since=10.days.ago master`).
+specified explicitly (e.g. `^master~10`), or implicitly (e.g.
+`master~10..master`, `--since=10.days.ago master`).
It is very important that the basis used be held by the destination.
It is okay to err on the side of caution, causing the bundle file
. They cannot have ASCII control characters (i.e. bytes whose
values are lower than \040, or \177 `DEL`), space, tilde `~`,
- caret `{caret}`, or colon `:` anywhere.
+ caret `^`, or colon `:` anywhere.
-. They cannot have question-mark `?`, asterisk `{asterisk}`, or open
+. They cannot have question-mark `?`, asterisk `*`, or open
bracket `[` anywhere. See the `--refspec-pattern` option below for
an exception to this rule.
reference name expressions (see linkgit:gitrevisions[7]):
. A double-dot `..` is often used as in `ref1..ref2`, and in some
- contexts this notation means `{caret}ref1 ref2` (i.e. not in
+ contexts this notation means `^ref1 ref2` (i.e. not in
`ref1` and in `ref2`).
-. A tilde `~` and caret `{caret}` are used to introduce the postfix
+. A tilde `~` and caret `^` are used to introduce the postfix
'nth parent' and 'peel onion' operation.
. A colon `:` is used as in `srcref:dstref` to mean "use srcref\'s
--refspec-pattern::
Interpret <refname> as a reference name pattern for a refspec
(as used with remote repositories). If this option is
- enabled, <refname> is allowed to contain a single `{asterisk}`
+ enabled, <refname> is allowed to contain a single `*`
in place of a one full pathname component (e.g.,
- `foo/{asterisk}/bar` but not `foo/bar{asterisk}`).
+ `foo/*/bar` but not `foo/bar*`).
--normalize::
Normalize 'refname' by removing any leading slash (`/`)
+
This means that you can use `git checkout -p` to selectively discard
edits from your current working tree. See the ``Interactive Mode''
-section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
+section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
<branch>::
Branch to checkout; if it refers to a branch (i.e., a name that,
commit, your HEAD becomes "detached" and you are no longer on
any branch (see below for details).
+
-As a special case, the `"@\{-N\}"` syntax for the N-th last branch
+As a special case, the `"@{-N}"` syntax for the N-th last branch
checks out the branch (instead of detaching). You may also specify
-`-` which is synonymous with `"@\{-1\}"`.
+`-` which is synonymous with `"@{-1}"`.
+
-As a further special case, you may use `"A\...B"` as a shortcut for the
+As a further special case, you may use `"A...B"` as a shortcut for the
merge base of `A` and `B` if there is exactly one merge base. You can
leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
Apply the changes introduced by all commits that are ancestors
of master but not of HEAD to produce new commits.
-`git cherry-pick master{tilde}4 master{tilde}2`::
+`git cherry-pick master~4 master~2`::
Apply the changes introduced by the fifth and third last
commits pointed to by master and create 2 new commits with
are in next but not HEAD to the current branch, creating a new
commit for each new change.
-`git rev-list --reverse master \-- README | git cherry-pick -n --stdin`::
+`git rev-list --reverse master -- README | git cherry-pick -n --stdin`::
Apply the changes introduced by all commits on the master
branch that touched README to the working tree and index,
5. by using the --interactive or --patch switches with the 'commit' command
to decide one by one which files or hunks should be part of the commit,
- before finalizing the operation. See the ``Interactive Mode`` section of
+ before finalizing the operation. See the ``Interactive Mode'' section of
linkgit:git-add[1] to learn how to operate these modes.
The `--dry-run` option can be used to obtain a
your working tree are temporarily stored to a staging area
called the "index" with 'git add'. A file can be
reverted back, only in the index but not in the working tree,
-to that of the last commit with `git reset HEAD \-- <file>`,
+to that of the last commit with `git reset HEAD -- <file>`,
which effectively reverts 'git add' and prevents the changes to
this file from participating in the next commit. After building
the state to be committed incrementally with these commands,
path expansion (see '--path' below). If no type specifier is passed, no
checks or transformations are performed on the value.
-The file-option can be one of '--system', '--global' or '--file'
-which specify where the values will be read from or written to.
-The default is to assume the config file of the current repository,
-.git/config unless defined otherwise with GIT_DIR and GIT_CONFIG
-(see <<FILES>>).
+When reading, the values are read from the system, global and
+repository local configuration files by default, and options
+'--system', '--global', '--local' and '--file <filename>' can be
+used to tell the command to read from only that location (see <<FILES>>).
+
+When writing, the new value is written to the repository local
+configuration file by default, and options '--system', '--global',
+'--file <filename>' can be used to tell the command to write to
+that location (you can say '--local' but that is the default).
This command will fail (with exit code ret) if:
'git-cvsserver' uses the Perl DBI module. Please also read
its documentation if changing these variables, especially
-about `DBI\->connect()`.
+about `DBI->connect()`.
gitcvs.dbname::
Database name. The exact meaning depends on the
[<git-rev-list-args>...]::
A list of arguments, acceptable to 'git rev-parse' and
'git rev-list', that specifies the specific objects and references
- to export. For example, `master{tilde}10..master` causes the
+ to export. For example, `master~10..master` causes the
current master reference to be exported along with all objects
added since its 10th ancestor commit.
----
from refs/heads/branch^0
----
-The `{caret}0` suffix is necessary as fast-import does not permit a branch to
+The `^0` suffix is necessary as fast-import does not permit a branch to
start from itself, and the branch is created in memory before the
-`from` command is even read from the input. Adding `{caret}0` will force
+`from` command is even read from the input. Adding `^0` will force
fast-import to resolve the commit through Git's revision parsing library,
rather than its internal branch table, thereby loading in the
existing value of the branch.
See `filemodify` above for a detailed description of `<path>`.
-Output uses the same format as `git ls-tree <tree> {litdd} <path>`:
+Output uses the same format as `git ls-tree <tree> -- <path>`:
====
<mode> SP ('blob' | 'tree' | 'commit') SP <dataref> HT <path> LF
--index-filter <command>::
This is the filter for rewriting the index. It is similar to the
tree filter but does not check out the tree, which makes it much
- faster. Frequently used with `git rm \--cached
- \--ignore-unmatch ...`, see EXAMPLES below. For hairy
+ faster. Frequently used with `git rm --cached
+ --ignore-unmatch ...`, see EXAMPLES below. For hairy
cases, see linkgit:git-update-index[1].
--parent-filter <command>::
a simple `rm filename` will fail for that tree and commit.
Thus you may instead want to use `rm -f filename` as the script.
-Using `\--index-filter` with 'git rm' yields a significantly faster
+Using `--index-filter` with 'git rm' yields a significantly faster
version. Like with using `rm filename`, `git rm --cached filename`
will fail if the file is absent from the tree of a commit. If you
want to "completely forget" a file, it does not matter when it entered
-history, so we also add `\--ignore-unmatch`:
+history, so we also add `--ignore-unmatch`:
--------------------------------------------------------------------------
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
-------------------------------------------------------
Thus you can, e.g., turn a library subdirectory into a repository of
-its own. Note the `\--` that separates 'filter-branch' options from
-revision options, and the `\--all` to rewrite all branches and tags.
+its own. Note the `--` that separates 'filter-branch' options from
+revision options, and the `--all` to rewrite all branches and tags.
To set a commit (which typically is at the tip of another
history) to be the parent of the current initial commit, in
------------------------------------
git-filter-branch is often used to get rid of a subset of files,
-usually with some combination of `\--index-filter` and
-`\--subdirectory-filter`. People expect the resulting repository to
+usually with some combination of `--index-filter` and
+`--subdirectory-filter`. People expect the resulting repository to
be smaller than the original, but you need a few more steps to
actually make it smaller, because git tries hard not to lose your
objects until you tell it to. First make sure that:
* You really removed all variants of a filename, if a blob was moved
- over its lifetime. `git log \--name-only \--follow \--all \--
- filename` can help you find renames.
+ over its lifetime. `git log --name-only --follow --all -- filename`
+ can help you find renames.
-* You really filtered all refs: use `\--tag-name-filter cat \--
- \--all` when calling git-filter-branch.
+* You really filtered all refs: use `--tag-name-filter cat -- --all`
+ when calling git-filter-branch.
Then there are two ways to get a smaller repository. A safer way is
to clone, that keeps your original intact.
-* Clone it with `git clone +++file:///path/to/repo+++`. The clone
+* Clone it with `git clone file:///path/to/repo`. The clone
will not have the removed objects. See linkgit:git-clone[1]. (Note
that cloning with a plain path just hardlinks everything!)
warned.
* Remove the original refs backed up by git-filter-branch: say `git
- for-each-ref \--format="%(refname)" refs/original/ | xargs -n 1 git
+ for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git
update-ref -d`.
-* Expire all reflogs with `git reflog expire \--expire=now \--all`.
+* Expire all reflogs with `git reflog expire --expire=now --all`.
-* Garbage collect all unreferenced objects with `git gc \--prune=now`
+* Garbage collect all unreferenced objects with `git gc --prune=now`
(or if your git-gc is not new enough to support arguments to
- `\--prune`, use `git repack -ad; git prune` instead).
+ `--prune`, use `git repack -ad; git prune` instead).
GIT
---
The first rule takes precedence in the case of a single <commit>. To
apply the second rule, i.e., format everything since the beginning of
history up until <commit>, use the '\--root' option: `git format-patch
-\--root <commit>`. If you want to format only <commit> itself, you
+--root <commit>`. If you want to format only <commit> itself, you
can do this with `git format-patch -1 <commit>`.
By default, each output file is numbered sequentially from 1, and uses the
The optional <style> argument can be either `shallow` or `deep`.
'shallow' threading makes every mail a reply to the head of the
series, where the head is chosen from the cover letter, the
-`\--in-reply-to`, and the first patch mail, in this order. 'deep'
+`--in-reply-to`, and the first patch mail, in this order. 'deep'
threading makes every mail a reply to the previous one.
+
The default is `--no-thread`, unless the 'format.thread' configuration
can be set to indicate how long historical reflog entries which
are not part of the current branch should remain available in
this repository. These types of entries are generally created as
-a result of using `git commit \--amend` or `git rebase` and are the
+a result of using `git commit --amend` or `git rebase` and are the
commits prior to the amend or rebase occurring. Since these changes
are not part of the current project most users will want to expire
them sooner. This option defaults to '30 days'.
Examples
--------
-`git grep {apostrophe}time_t{apostrophe} \-- {apostrophe}*.[ch]{apostrophe}`::
+`git grep 'time_t' -- '*.[ch]'`::
Looks for `time_t` in all tracked .c and .h files in the working
directory and its subdirectories.
-`git grep -e {apostrophe}#define{apostrophe} --and \( -e MAX_PATH -e PATH_MAX \)`::
+`git grep -e '#define' --and \( -e MAX_PATH -e PATH_MAX \)`::
Looks for a line that has `#define` and either `MAX_PATH` or
`PATH_MAX`.
Show all commits since version 'v2.6.12' that changed any file
in the include/scsi or drivers/scsi subdirectories
-`git log --since="2 weeks ago" \-- gitk`::
+`git log --since="2 weeks ago" -- gitk`::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named
second object). This subcommand is equivalent to:
`git notes add [-f] -C $(git notes list <from-object>) <to-object>`
+
-In `\--stdin` mode, take lines in the format
+In `--stdin` mode, take lines in the format
+
----------
<from-object> SP <to-object> [ SP <rest> ] LF
A recommended practice to deal with a repository with too many
refs is to pack its refs with `--all --prune` once, and
-occasionally run `git pack-refs \--prune`. Tags are by
+occasionally run `git pack-refs --prune`. Tags are by
definition stationary and are not expected to change. Branch
heads will be packed with the initial `pack-refs --all`, but
only the currently active branch heads will become unpacked,
+
See `pull.rebase`, `branch.<name>.rebase` and `branch.autosetuprebase` in
linkgit:git-config[1] if you want to make `git pull` always use
-`{litdd}rebase` instead of merging.
+`--rebase` instead of merging.
+
[NOTE]
This is a potentially _dangerous_ mode of operation.
<refspec>...::
The format of a <refspec> parameter is an optional plus
- `{plus}`, followed by the source ref <src>, followed
+ `+`, followed by the source ref <src>, followed
by a colon `:`, followed by the destination ref <dst>.
It is used to specify with what <src> object the <dst> ref
in the remote repository is to be updated.
+
The object referenced by <src> is used to update the <dst> reference
on the remote side, but by default this is only allowed if the
-update can fast-forward <dst>. By having the optional leading `{plus}`,
+update can fast-forward <dst>. By having the optional leading `+`,
you can tell git to update the <dst> ref even when the update is not a
fast-forward. This does *not* attempt to merge <src> into <dst>. See
EXAMPLES below for details.
Pushing an empty <src> allows you to delete the <dst> ref from
the remote repository.
+
-The special refspec `:` (or `{plus}:` to allow non-fast-forward updates)
+The special refspec `:` (or `+:` to allow non-fast-forward updates)
directs git to push "matching" branches: for every branch that exists on
the local side, the remote side is updated if a branch of the same name
already exists on the remote side. This is the default operation mode
Remove remote branches that don't have a local counterpart. For example
a remote branch `tmp` will be removed if a local branch with the same
name doesn't exist any more. This also respects refspecs, e.g.
- `git push --prune remote refs/heads/{asterisk}:refs/tmp/{asterisk}` would
+ `git push --prune remote refs/heads/*:refs/tmp/*` would
make sure that remote `refs/tmp/foo` will be removed if `refs/heads/foo`
doesn't exist.
flag::
A single character indicating the status of the ref:
(space);; for a successfully pushed fast-forward;
-`{plus}`;; for a successful forced update;
+`+`;; for a successful forced update;
`-`;; for a successfully deleted ref;
`*`;; for a successfully pushed new ref;
`!`;; for a ref that was rejected or failed to push; and
For a successfully pushed ref, the summary shows the old and new
values of the ref in a form suitable for using as an argument to
`git log` (this is `<old>..<new>` in most cases, and
- `<old>\...<new>` for forced non-fast-forward updates).
+ `<old>...<new>` for forced non-fast-forward updates).
+
For a failed update, more details are given:
+
Find a ref that matches `experimental` in the `origin` repository
(e.g. `refs/heads/experimental`), and delete it.
-`git push origin {plus}dev:master`::
+`git push origin +dev:master`::
Update the origin repository's master branch with the dev branch,
allowing non-fast-forward updates. *This can leave unreferenced
commits dangling in the origin repository.* Consider the
-X <strategy-option>::
--strategy-option=<strategy-option>::
Pass the <strategy-option> through to the merge strategy.
- This implies `\--merge` and, if no strategy has been
+ This implies `--merge` and, if no strategy has been
specified, `-s recursive`. Note the reversal of 'ours' and
'theirs' as noted in above for the `-m` option.
Hard case: The changes are not the same.::
This happens if the 'subsystem' rebase had conflicts, or used
- `\--interactive` to omit, edit, squash, or fixup commits; or
- if the upstream used one of `commit \--amend`, `reset`, or
+ `--interactive` to omit, edit, squash, or fixup commits; or
+ if the upstream used one of `commit --amend`, `reset`, or
`filter-branch`.
NOTE: While an "easy case recovery" sometimes appears to be successful
even in the hard case, it may have unintended consequences. For
example, a commit that was removed via `git rebase
- \--interactive` will be **resurrected**!
+ --interactive` will be **resurrected**!
The idea is to manually tell 'git rebase' "where the old 'subsystem'
ended and your 'topic' began", that is, what the old merge-base
of the old 'subsystem', for example:
* With the 'subsystem' reflog: after 'git fetch', the old tip of
- 'subsystem' is at `subsystem@\{1}`. Subsequent fetches will
+ 'subsystem' is at `subsystem@{1}`. Subsequent fetches will
increase the number. (See linkgit:git-reflog[1].)
* Relative to the tip of 'topic': knowing that your 'topic' has three
see linkgit:git-log[1].
The reflog is useful in various git commands, to specify the old value
-of a reference. For example, `HEAD@\{2\}` means "where HEAD used to be
-two moves ago", `master@\{one.week.ago\}` means "where master used to
+of a reference. For example, `HEAD@{2}` means "where HEAD used to be
+two moves ago", `master@{one.week.ago}` means "where master used to
point to one week ago", and so on. See linkgit:gitrevisions[7] for
more details.
To delete single entries from the reflog, use the subcommand "delete"
-and specify the _exact_ entry (e.g. "`git reflog delete master@\{2\}`").
+and specify the _exact_ entry (e.g. "`git reflog delete master@{2}`").
OPTIONS
capability use this.
+
A helper advertising the capability
-`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
+`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.
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 {asterisk}:{asterisk}`.
+there is an implied `refspec *:*`.
Capabilities for Pushing
~~~~~~~~~~~~~~~~~~~~~~~~
This modifies the 'import' capability.
+
A helper advertising
-`refspec refs/heads/{asterisk}:refs/svn/origin/branches/{asterisk}`
+`refspec refs/heads/*:refs/svn/origin/branches/*`
in its capabilities is saying that, when it handles
`import refs/heads/topic`, the stream it outputs will update the
`refs/svn/origin/branches/topic` ref.
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 {asterisk}:{asterisk}`.
+there is an implied `refspec *:*`.
INVOCATION
----------
With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
up to point at remote's `<master>` branch. See also the set-head command.
+
-When a fetch mirror is created with `\--mirror=fetch`, the refs will not
+When a fetch mirror is created with `--mirror=fetch`, the refs will not
be stored in the 'refs/remotes/' namespace, but rather everything in
'refs/' on the remote will be directly mirrored into 'refs/' in the
local repository. This option only makes sense in bare repositories,
because a fetch would overwrite any local commits.
+
-When a push mirror is created with `\--mirror=push`, then `git push`
-will always behave as if `\--mirror` was passed.
+When a push mirror is created with `--mirror=push`, then `git push`
+will always behave as if `--mirror` was passed.
'rename'::
The commits marked with `*` touch the same area in the same
file; you need to resolve the conflicts when creating the commit
-marked with `{plus}`. Then you can test the result to make sure your
+marked with `+`. Then you can test the result to make sure your
work-in-progress still works with what is in the latest master.
After this test merge, there are two ways to continue your work
on the topic. The easiest is to build on top of the test merge
-commit `{plus}`, and when your work in the topic branch is finally
+commit `+`, and when your work in the topic branch is finally
ready, pull the topic branch into master, and/or ask the
upstream to pull from you. By that time, however, the master or
-the upstream might have been advanced since the test merge `{plus}`,
+the upstream might have been advanced since the test merge `+`,
in which case the final commit graph would look like this:
------------
+
This means that `git reset -p` is the opposite of `git add -p`, i.e.
you can use it to selectively reset hunks. See the ``Interactive Mode''
-section of linkgit:git-add[1] to learn how to operate the `\--patch` mode.
+section of linkgit:git-add[1] to learn how to operate the `--patch` mode.
'git reset' --<mode> [<commit>]::
This form resets the current branch head to <commit> and
+
If a `pattern` is given, only refs matching the given shell glob are
shown. If the pattern does not contain a globbing character (`?`,
-`{asterisk}`, or `[`), it is turned into a prefix match by
-appending `/{asterisk}`.
+`*`, or `[`), it is turned into a prefix match by appending `/*`.
--glob=pattern::
Show all refs matching the shell glob pattern `pattern`. If
the pattern does not start with `refs/`, this is automatically
prepended. If the pattern does not contain a globbing
- character (`?`, `{asterisk}`, or `[`), it is turned into a prefix
- match by appending `/{asterisk}`.
+ character (`?`, `*`, or `[`), it is turned into a prefix
+ match by appending `/*`.
--show-toplevel::
Show the absolute path of the top-level directory.
should see linkgit:git-reset[1], particularly the '--hard' option. If
you want to extract specific files as they were in another commit, you
should see linkgit:git-checkout[1], specifically the `git checkout
-<commit> \-- <filename>` syntax. Take care with these alternatives as
+<commit> -- <filename>` syntax. Take care with these alternatives as
both will discard uncommitted changes in your working directory.
OPTIONS
Revert the changes specified by the fourth last commit in HEAD
and create a new commit with the reverted changes.
-`git revert -n master{tilde}5..master{tilde}2`::
+`git revert -n master~5..master~2`::
Revert the changes done by commits from the fifth last commit
in master (included) to the third last commit in master
File globbing matches across directory boundaries. Thus, given
two directories `d` and `d2`, there is a difference between
-using `git rm {apostrophe}d{asterisk}{apostrophe}` and
-`git rm {apostrophe}d/{asterisk}{apostrophe}`, as the former will
+using `git rm 'd*'` and `git rm 'd/*'`, as the former will
also remove all of directory `d2`.
REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM
--format[=<format>]::
Instead of the commit subject, use some other information to
describe each commit. '<format>' can be any string accepted
- by the `--format` option of 'git log', such as '{asterisk} [%h] %s'.
+ by the `--format` option of 'git log', such as '* [%h] %s'.
(See the "PRETTY FORMATS" section of linkgit:git-log[1].)
Each pretty-printed commit will be rewrapped before it is shown.
--exclude-existing[=<pattern>]::
Make 'git show-ref' act as a filter that reads refs from stdin of the
- form "`{caret}(?:<anything>\s)?<refname>(?:{backslash}{caret}{})?$`"
+ form "`^(?:<anything>\s)?<refname>(?:\^{})?$`"
and performs the following actions on each:
(1) strip "{caret}{}" at the end of line if any;
(2) ignore if pattern is provided and does not head-match refname;
Shows the tag `v1.0.0`, along with the object the tags
points at.
-`git show v1.0.0^\{tree\}`::
+`git show v1.0.0^{tree}`::
Shows the tree pointed to by the tag `v1.0.0`.
-`git show -s --format=%s v1.0.0^\{commit\}`::
+`git show -s --format=%s v1.0.0^{commit}`::
Shows the subject of the commit pointed to by the
tag `v1.0.0`.
The latest stash you created is stored in `refs/stash`; older
stashes are found in the reflog of this reference and can be named using
-the usual reflog syntax (e.g. `stash@\{0}` is the most recently
-created stash, `stash@\{1}` is the one before it, `stash@\{2.hours.ago}`
+the usual reflog syntax (e.g. `stash@{0}` is the most recently
+created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}`
is also possible).
OPTIONS
of your repository, and its worktree contains only the changes you
selected interactively. The selected changes are then rolled back
from your worktree. See the ``Interactive Mode'' section of
-linkgit:git-add[1] to learn how to operate the `\--patch` mode.
+linkgit:git-add[1] to learn how to operate the `--patch` mode.
+
The `--patch` option implies `--keep-index`. You can use
`--no-keep-index` to override this.
list [<options>]::
List the stashes that you currently have. Each 'stash' is listed
- with its name (e.g. `stash@\{0}` is the latest stash, `stash@\{1}` is
+ with its name (e.g. `stash@{0}` is the latest stash, `stash@{1}` is
the one before, etc.), the name of the branch that was current when the
stash was made, and a short description of the commit the stash was
based on.
stashed state and its original parent. When no `<stash>` is given,
shows the latest one. By default, the command shows the diffstat, but
it will accept any format known to 'git diff' (e.g., `git stash show
- -p stash@\{1}` to view the second most recent stash in patch form).
+ -p stash@{1}` to view the second most recent stash in patch form).
pop [--index] [-q|--quiet] [<stash>]::
have conflicts (which are stored in the index, where you therefore can no
longer apply the changes as they were originally).
+
-When no `<stash>` is given, `stash@\{0}` is assumed, otherwise `<stash>` must
-be a reference of the form `stash@\{<revision>}`.
+When no `<stash>` is given, `stash@{0}` is assumed, otherwise `<stash>` must
+be a reference of the form `stash@{<revision>}`.
apply [--index] [-q|--quiet] [<stash>]::
drop [-q|--quiet] [<stash>]::
Remove a single stashed state from the stash list. When no `<stash>`
- is given, it removes the latest one. i.e. `stash@\{0}`, otherwise
+ is given, it removes the latest one. i.e. `stash@{0}`, otherwise
`<stash>` must a valid stash log reference of the form
- `stash@\{<revision>}`.
+ `stash@{<revision>}`.
create::
XY PATH1 -> PATH2
-where `PATH1` is the path in the `HEAD`, and the ` \-> PATH2` part is
+where `PATH1` is the path in the `HEAD`, and the " `-> PATH2`" part is
shown only when `PATH1` corresponds to a different path in the
index/worktree (i.e. the file is renamed). The 'XY' is a two-letter
status code.
-The fields (including the `\->`) are separated from each other by a
+The fields (including the `->`) are separated from each other by a
single space. If a filename contains whitespace or other nonprintable
characters, that field will be quoted in the manner of a C string
literal: surrounded by ASCII double quote (34) characters, and with
Submodules are composed from a so-called `gitlink` tree entry
in the main repository that refers to a particular commit object
within the inner repository that is completely separate.
-A record in the `.gitmodules` file at the root of the source
-tree assigns a logical name to the submodule and describes
-the default URL the submodule shall be cloned from.
+A record in the `.gitmodules` (see linkgit:gitmodules[5]) file at the
+root of the source tree assigns a logical name to the submodule and
+describes the default URL the submodule shall be cloned from.
The logical name can be used for overriding this URL within your
local repository configuration (see 'submodule init').
checkout the commit specified in the index of the containing repository.
This will make the submodules HEAD be detached unless `--rebase` or
`--merge` is specified or the key `submodule.$name.update` is set to
- `rebase`, `merge` or `none`.
+ `rebase`, `merge` or `none`. `none` can be overriden by specifying
+ `--checkout`.
+
If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the
+
If `--recursive` is specified, this command will recurse into the
registered submodules, and update any nested submodules within.
-+
-If the configuration key `submodule.$name.update` is set to `none` the
-submodule with name `$name` will not be updated by default. This can be
-overriden by adding `--checkout` to the command.
summary::
Show commit summary between the given commit (defaults to HEAD) and
Create a tarball for v1.4.0 release.
-`git tar-tree v1.4.0{caret}\{tree\} git-1.4.0 | gzip >git-1.4.0.tar.gz`::
+`git tar-tree v1.4.0^{tree} git-1.4.0 | gzip >git-1.4.0.tar.gz`::
Create a tarball for v1.4.0 release, but without a
global extended pax header.
Show as patches the commits since version 'v2.6.12' that changed
any file in the include/scsi or drivers/scsi subdirectories
-`git whatchanged --since="2 weeks ago" \-- gitk`::
+`git whatchanged --since="2 weeks ago" -- gitk`::
Show the changes during the last two weeks to the file 'gitk'.
The "--" is necessary to avoid confusion with the *branch* named
branch of the `git.git` repository.
Documentation for older releases are available here:
-* link:v1.7.10.1/git.html[documentation for release 1.7.10.1]
+* link:v1.7.10.2/git.html[documentation for release 1.7.10.2]
* release notes for
+ link:RelNotes/1.7.10.2.txt[1.7.10.2],
link:RelNotes/1.7.10.1.txt[1.7.10.1],
link:RelNotes/1.7.10.txt[1.7.10].
are paths.
* When an argument can be misunderstood as either a revision or a path,
- they can be disambiguated by placing `\--` between them.
- E.g. `git diff \-- HEAD` is, "I have a file called HEAD in my work
+ they can be disambiguated by placing `--` between them.
+ E.g. `git diff -- HEAD` is, "I have a file called HEAD in my work
tree. Please show changes between the version I staged in the index
and what I have in the work tree for that file". not "show difference
between the HEAD commit and the work tree as a whole". You can say
- `git diff HEAD \--` to ask for the latter.
+ `git diff HEAD --` to ask for the latter.
- * Without disambiguating `\--`, git makes a reasonable guess, but errors
+ * Without disambiguating `--`, git makes a reasonable guess, but errors
out and asking you to disambiguate when ambiguous. E.g. if you have a
file called HEAD in your work tree, `git diff HEAD` is ambiguous, and
- you have to say either `git diff HEAD \--` or `git diff \-- HEAD` to
+ you have to say either `git diff HEAD --` or `git diff -- HEAD` to
disambiguate.
When writing a script that is expected to handle random user-input, it is
a good practice to make it explicit which arguments are which by placing
-disambiguating `\--` at appropriate places.
+disambiguating `--` at appropriate places.
Here are the rules regarding the "flags" that you should follow when you are
scripting git:
program normally just takes a list of filenames you want to update, but
to avoid trivial mistakes, it refuses to add new entries to the index
(or remove existing ones) unless you explicitly tell it that you're
-adding a new entry with the `\--add` flag (or removing an entry with the
-`\--remove`) flag.
+adding a new entry with the `--add` flag (or removing an entry with the
+`--remove`) flag.
So to populate the index with the two files you just created, you can do
which ends up doing the above for you.
In other words, 'git diff-index' normally compares a tree against the
-working tree, but when given the `\--cached` flag, it is told to
+working tree, but when given the `--cached` flag, it is told to
instead compare against just the index cache contents, and ignore the
current working tree state entirely. Since we just wrote the index
-file to HEAD, doing `git diff-index \--cached -p HEAD` should thus return
+file to HEAD, doing `git diff-index --cached -p HEAD` should thus return
an empty set of differences, and that's exactly what it does.
[NOTE]
comparisons, and saying that it compares a tree against the working
tree is thus not strictly accurate. In particular, the list of
files to compare (the "meta-data") *always* comes from the index file,
-regardless of whether the `\--cached` flag is used or not. The `\--cached`
+regardless of whether the `--cached` flag is used or not. The `--cached`
flag really only determines whether the file *contents* to be compared
come from the working tree or not.
$ git update-index hello
------------------------------------------------
-(note how we didn't need the `\--add` flag this time, since git knew
+(note how we didn't need the `--add` flag this time, since git knew
about the file already).
Note what happens to the different 'git diff-{asterisk}' versions here.
When using the above two commands, the initial commit will be shown.
If this is a problem because it is huge, you can hide it by setting
the log.showroot configuration variable to false. Having this, you
-can still show it for each command just adding the `\--root` option,
+can still show it for each command just adding the `--root` option,
which is a flag for 'git diff-tree' accepted by both commands.
With that, you should now be having some inkling of what git does, and
$ gitk --all
----------------
-will show you graphically both of your branches (that's what the `\--all`
+will show you graphically both of your branches (that's what the `--all`
means: normally it will just show you your current `HEAD`) and their
histories. You can also see exactly how they came to be from a common
source.
(which is correct, so never mind), and you can write a small merge
message about your adventures in 'git merge'-land.
-After you're done, start up `gitk \--all` to see graphically what the
+After you're done, start up `gitk --all` to see graphically what the
history looks like. Notice that `mybranch` still exists, and you can
switch to it, and continue to work with it if you want to. The
`mybranch` branch will not contain the merge, but next time you merge it
The first two lines indicate that it is showing the two branches
and the first line of the commit log message from their
top-of-the-tree commits, you are currently on `master` branch
-(notice the asterisk `{asterisk}` character), and the first column for
+(notice the asterisk `*` character), and the first column for
the later output lines is used to show commits contained in the
`master` branch, and the second column for the `mybranch`
branch. Three commits are shown along with their log messages.
-All of them have non blank characters in the first column (`{asterisk}`
+All of them have non blank characters in the first column (`*`
shows an ordinary commit on the current branch, `-` is a merge commit), which
means they are now part of the `master` branch. Only the "Some
work" commit has the plus `+` character in the second column,
the tree of your branch to that of the `master` branch. This is
often called 'fast-forward' merge.
-You can run `gitk \--all` again to see how the commit ancestry
+You can run `gitk --all` again to see how the commit ancestry
looks like, or run 'show-branch', which tells you this.
------------------------------------------------
fairly quickly, leaving only a handful of real changes in non-zero
stages.
-To look at only non-zero stages, use `\--unmerged` flag:
+To look at only non-zero stages, use `--unmerged` flag:
------------
$ git ls-files --unmerged
directory.
[NOTE]
-You will see two files, `pack-{asterisk}.pack` and `pack-{asterisk}.idx`,
+You will see two files, `pack-*.pack` and `pack-*.idx`,
in `.git/objects/pack` directory. They are closely related to
each other, and if you ever copy them by hand to a different
repository for whatever reason, you should make sure you copy
---------------------
Options for a credential context can be configured either in
-`credential.\*` (which applies to all credentials), or
-`credential.<url>.\*`, where <url> matches the context as described
+`credential.*` (which applies to all credentials), or
+`credential.<url>.*`, where <url> matches the context as described
above.
The following options are available in either location:
number after the "-M" or "-C" option (e.g. "-M8" to tell it to use
8/10 = 80%).
-Note. When the "-C" option is used with `\--find-copies-harder`
+Note. When the "-C" option is used with `--find-copies-harder`
option, 'git diff-{asterisk}' commands feed unmodified filepairs to
diffcore mechanism as well as modified ones. This lets the copy
detector consider unmodified files as copy source candidates at
-the expense of making it slower. Without `\--find-copies-harder`,
+the expense of making it slower. Without `--find-copies-harder`,
'git diff-{asterisk}' commands can detect copies only if the file that was
copied happened to have been modified in the same changeset.
This transformation is used to find filepairs that represent
changes that touch a specified string, and is controlled by the
--S option and the `\--pickaxe-all` option to the 'git diff-{asterisk}'
+-S option and the `--pickaxe-all` option to the 'git diff-*'
commands.
When diffcore-pickaxe is in use, it checks if there are
"the string appeared in this changeset". It also checks for the
opposite case that loses the specified string.
-When `\--pickaxe-all` is not in effect, diffcore-pickaxe leaves
+When `--pickaxe-all` is not in effect, diffcore-pickaxe leaves
only such filepairs that touch the specified string in its
-output. When `\--pickaxe-all` is used, diffcore-pickaxe leaves all
+output. When `--pickaxe-all` is used, diffcore-pickaxe leaves all
filepairs intact if there is such a filepair, or makes the
output empty otherwise. The latter behaviour is designed to
make reviewing of the changes in the context of the whole
~~~~~~~~~~
This hook is invoked by 'git commit', and can be bypassed
-with `\--no-verify` option. It takes no parameter, and is
+with `--no-verify` option. It takes no parameter, and is
invoked before obtaining the proposed commit log message and
making a commit. Exiting with non-zero status from this script
causes the 'git commit' to abort.
configuration option `commit.template` is set); `merge` (if the
commit is a merge or a `.git/MERGE_MSG` file exists); `squash`
(if a `.git/SQUASH_MSG` file exists); or `commit`, followed by
-a commit SHA1 (if a `-c`, `-C` or `\--amend` option was given).
+a commit SHA1 (if a `-c`, `-C` or `--amend` option was given).
If the exit status is non-zero, 'git commit' will abort.
The purpose of the hook is to edit the message file in place, and
-it is not suppressed by the `\--no-verify` option. A non-zero exit
+it is not suppressed by the `--no-verify` option. A non-zero exit
means a failure of the hook and aborts the commit. It should not
be used as replacement for pre-commit hook.
~~~~~~~~~~
This hook is invoked by 'git commit', and can be bypassed
-with `\--no-verify` option. It takes a single parameter, the
+with `--no-verify` option. It takes a single parameter, the
name of the file that holds the proposed commit log message.
Exiting with non-zero status causes the 'git commit' to
abort.
the commit specified in the superproject. If 'merge', the commit
specified in the superproject will be merged into the current branch
in the submodule.
+ If 'none', the submodule with name `$name` will not be updated
+ by default.
+
This config option is overridden if 'git submodule update' is given
- the '--merge' or '--rebase' options.
+ the '--merge', '--rebase' or '--checkout' options.
submodule.<name>.fetchRecurseSubmodules::
This option can be used to control recursive fetching of this
forks::
If this feature is enabled, gitweb considers projects in
subdirectories of project root (basename) to be forks of existing
- projects. For each project `$projname.git`, projects in the
- `$projname/` directory and its subdirectories will not be
- shown in the main projects list. Instead, a \'+' mark is shown
- next to `$projname`, which links to a "forks" view that lists all
- the forks (all projects in `$projname/` subdirectory). Additionally
+ projects. For each project +$projname.git+, projects in the
+ +$projname/+ directory and its subdirectories will not be
+ shown in the main projects list. Instead, a \'\+' mark is shown
+ next to +$projname+, which links to a "forks" view that lists all
+ the forks (all projects in +$projname/+ subdirectory). Additionally
a "forks" view for a project is linked from project summary page.
+
-If the project list is taken from a file (`$projects_list` points to a
+If the project list is taken from a file (+$projects_list+ points to a
file), forks are only recognized if they are listed after the main project
in that file.
+
beginning. It is always easier to squash a few commits together than
to split one big commit into several. Don't be afraid of making too
small or imperfect steps along the way. You can always go back later
-and edit the commits with `git rebase \--interactive` before you
-publish them. You can use `git stash save \--keep-index` to run the
+and edit the commits with `git rebase --interactive` before you
+publish them. You can use `git stash save --keep-index` to run the
test suite independent of other uncommitted changes; see the EXAMPLES
section of linkgit:git-stash[1].
- '%b': body
- '%B': raw body (unwrapped subject and body)
- '%N': commit notes
-- '%gD': reflog selector, e.g., `refs/stash@\{1\}`
-- '%gd': shortened reflog selector, e.g., `stash@\{1\}`
+- '%gD': reflog selector, e.g., `refs/stash@{1}`
+- '%gd': shortened reflog selector, e.g., `stash@{1}`
- '%gn': reflog identity name
- '%gN': reflog identity name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1])
- '%ge': reflog identity email
`git log -g`). The `%d` placeholder will use the "short" decoration
format if `--decorate` was not already provided on the command line.
-If you add a `{plus}` (plus sign) after '%' of a placeholder, a line-feed
+If you add a `+` (plus sign) after '%' of a placeholder, a line-feed
is inserted immediately before the expansion if and only if the
placeholder expands to a non-empty string.
<refspec>::
The format of a <refspec> parameter is an optional plus
- `{plus}`, followed by the source ref <src>, followed
+ `+`, followed by the source ref <src>, followed
by a colon `:`, followed by the destination ref <dst>.
+
The remote ref that matches <src>
+
For example, `--cherry-pick --right-only A...B` omits those
commits from `B` which are in `A` or are patch-equivalent to a commit in
-`A`. In other words, this lists the `{plus}` commits from `git cherry A B`.
+`A`. In other words, this lists the `+` commits from `git cherry A B`.
More precisely, `--cherry-pick --right-only --no-merges` gives the exact
list.
`---------'
-----------------------------------------------------------------------
+
-Note the major differences in `N` and `P` over '\--full-history':
+Note the major differences in `N` and `P` over '--full-history':
+
--
* `N`'s parent list had `I` removed, because it is an ancestor of the
When we want to find out what commits in `M` are contaminated with the
bug introduced by `D` and need fixing, however, we might want to view
only the subset of 'D..M' that are actually descendants of `D`, i.e.
-excluding `C` and `K`. This is exactly what the '\--ancestry-path'
+excluding `C` and `K`. This is exactly what the '--ancestry-path'
option does. Applied to the 'D..M' range, it results in:
+
-----------------------------------------------------------------------
`argv_array_push`::
Push a copy of a string onto the end of the array.
+`argv_array_pushl`::
+ Push a list of strings onto the end of the array. The arguments
+ should be a list of `const char *` strings, terminated by a NULL
+ argument.
+
`argv_array_pushf`::
Format a string and push it onto the end of the array. This is a
convenience wrapper combining `strbuf_addf` and `argv_array_push`.
* There are basically two forms of options:
'Short options' consist of one dash (`-`) and one alphanumeric
character.
- 'Long options' begin with two dashes (`\--`) and some
+ 'Long options' begin with two dashes (`--`) and some
alphanumeric characters.
* Options are case-sensitive.
* 'sticked' and 'separate form' of options with arguments.
`-oArg` is sticked, `-o Arg` is separate form.
- `\--option=Arg` is sticked, `\--option Arg` is separate form.
+ `--option=Arg` is sticked, `--option Arg` is separate form.
* Long options may be 'abbreviated', as long as the abbreviation
is unambiguous.
* Short options may be bundled, e.g. `-a -b` can be specified as `-ab`.
* Boolean long options can be 'negated' (or 'unset') by prepending
- `no-`, e.g. `\--no-abbrev` instead of `\--abbrev`. Conversely,
+ `no-`, e.g. `--no-abbrev` instead of `--abbrev`. Conversely,
options that begin with `no-` can be 'negated' by removing it.
-* Options and non-option arguments can clearly be separated using the `\--`
- option, e.g. `-a -b \--option \-- \--this-is-a-file` indicates that
- `\--this-is-a-file` must not be processed as an option.
+* Options and non-option arguments can clearly be separated using the `--`
+ option, e.g. `-a -b --option -- --this-is-a-file` indicates that
+ `--this-is-a-file` must not be processed as an option.
Steps to parse options
----------------------
Flags are the bitwise-or of:
`PARSE_OPT_KEEP_DASHDASH`::
- Keep the `\--` that usually separates options from
+ Keep the `--` that usually separates options from
non-option arguments.
`PARSE_OPT_STOP_AT_NON_OPTION`::
There are some macros to easily define options:
`OPT__ABBREV(&int_var)`::
- Add `\--abbrev[=<n>]`.
+ Add `--abbrev[=<n>]`.
`OPT__COLOR(&int_var, description)`::
- Add `\--color[=<when>]` and `--no-color`.
+ Add `--color[=<when>]` and `--no-color`.
`OPT__DRY_RUN(&int_var, description)`::
- Add `-n, \--dry-run`.
+ Add `-n, --dry-run`.
`OPT__FORCE(&int_var, description)`::
- Add `-f, \--force`.
+ Add `-f, --force`.
`OPT__QUIET(&int_var, description)`::
- Add `-q, \--quiet`.
+ Add `-q, --quiet`.
`OPT__VERBOSE(&int_var, description)`::
- Add `-v, \--verbose`.
+ Add `-v, --verbose`.
`OPT_GROUP(description)`::
Start an option group. `description` is a short string that
If not stated otherwise, interpret the arguments as follows:
* `short` is a character for the short option
- (e.g. `{apostrophe}e{apostrophe}` for `-e`, use `0` to omit),
+ (e.g. `'e'` for `-e`, use `0` to omit),
* `long` is a string for the long option
- (e.g. `"example"` for `\--example`, use `NULL` to omit),
+ (e.g. `"example"` for `--example`, use `NULL` to omit),
* `int_var` is an integer variable,
The callback mechanism is as follows:
* Inside `func`, the only interesting member of the structure
- given by `opt` is the void pointer `opt\->value`.
- `\*opt\->value` will be the value that is saved into `var`, if you
+ given by `opt` is the void pointer `opt->value`.
+ `*opt->value` will be the value that is saved into `var`, if you
use `OPT_CALLBACK()`.
- For example, do `*(unsigned long *)opt\->value = 42;` to get 42
+ For example, do `*(unsigned long *)opt->value = 42;` to get 42
into an `unsigned long` variable.
* Return value `0` indicates success and non-zero return
A simple clone may look like this (with no 'have' lines):
----
- C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d\0multi_ack \
+ C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack \
side-band-64k ofs-delta\n
C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
An incremental update (fetch) response might look like this:
----
- C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d\0multi_ack \
+ C: 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack \
side-band-64k ofs-delta\n
C: 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe\n
C: 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a\n
. They cannot have ASCII control characters (i.e. bytes whose
values are lower than \040, or \177 `DEL`), space, tilde `~`,
- caret `{caret}`, colon `:`, question-mark `?`, asterisk `*`,
+ caret `^`, colon `:`, question-mark `?`, asterisk `*`,
or open bracket `[` anywhere.
. They cannot end with a slash `/` nor a dot `.`.
Reflogs
^^^^^^^
-Say you modify a branch with `linkgit:git-reset[1] --hard`, and then
+Say you modify a branch with +linkgit:git-reset[1] \--hard+, and then
realize that the branch was the only reference you had to that point in
history.
If you are interested in more details of the revision walking process,
just have a look at the first implementation of `cmd_log()`; call
-`git show v1.3.0{tilde}155^2{tilde}4` and scroll down to that function (note that you
+`git show v1.3.0~155^2~4` and scroll down to that function (note that you
no longer need to call `setup_pager()` directly).
Nowadays, `git log` is a builtin, which means that it is _contained_ in the
negative numbers in case of different errors--and 0 on success.
- the variable `sha1` in the function signature of `get_sha1()` is `unsigned
- char {asterisk}`, but is actually expected to be a pointer to `unsigned
+ char *`, but is actually expected to be a pointer to `unsigned
char[20]`. This variable will contain the 160-bit SHA-1 of the given
- commit. Note that whenever a SHA-1 is passed as `unsigned char {asterisk}`, it
+ commit. Note that whenever a SHA-1 is passed as `unsigned char *`, it
is the binary representation, as opposed to the ASCII representation in
hex characters, which is passed as `char *`.
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v1.7.10.1
+DEF_VER=v1.7.10.2
LF='
'
-Documentation/RelNotes/1.7.10.2.txt
\ No newline at end of file
+Documentation/RelNotes/1.7.10.3.txt
\ No newline at end of file
#include "cache.h"
int advice_push_nonfastforward = 1;
+int advice_push_non_ff_current = 1;
+int advice_push_non_ff_default = 1;
+int advice_push_non_ff_matching = 1;
int advice_status_hints = 1;
int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1;
int *preference;
} advice_config[] = {
{ "pushnonfastforward", &advice_push_nonfastforward },
+ { "pushnonffcurrent", &advice_push_non_ff_current },
+ { "pushnonffdefault", &advice_push_non_ff_default },
+ { "pushnonffmatching", &advice_push_non_ff_matching },
{ "statushints", &advice_status_hints },
{ "commitbeforemerge", &advice_commit_before_merge },
{ "resolveconflict", &advice_resolve_conflict },
#include "git-compat-util.h"
extern int advice_push_nonfastforward;
+extern int advice_push_non_ff_current;
+extern int advice_push_non_ff_default;
+extern int advice_push_non_ff_matching;
extern int advice_status_hints;
extern int advice_commit_before_merge;
extern int advice_resolve_conflict;
#include "argv-array.h"
#include "strbuf.h"
-static const char *empty_argv_storage = NULL;
-const char **empty_argv = &empty_argv_storage;
+const char *empty_argv[] = { NULL };
void argv_array_init(struct argv_array *array)
{
argv_array_push_nodup(array, strbuf_detach(&v, NULL));
}
+void argv_array_pushl(struct argv_array *array, ...)
+{
+ va_list ap;
+ const char *arg;
+
+ va_start(ap, array);
+ while((arg = va_arg(ap, const char *)))
+ argv_array_push(array, arg);
+ va_end(ap);
+}
+
void argv_array_clear(struct argv_array *array)
{
if (array->argv != empty_argv) {
#ifndef ARGV_ARRAY_H
#define ARGV_ARRAY_H
-extern const char **empty_argv;
+extern const char *empty_argv[];
struct argv_array {
const char **argv;
void argv_array_push(struct argv_array *, const char *);
__attribute__((format (printf,2,3)))
void argv_array_pushf(struct argv_array *, const char *fmt, ...);
+void argv_array_pushl(struct argv_array *, ...);
void argv_array_clear(struct argv_array *);
#endif /* ARGV_ARRAY_H */
* HEAD. If it is not reachable from any ref, this is the last chance
* for the user to do so without resorting to reflog.
*/
-static void orphaned_commit_warning(struct commit *commit)
+static void orphaned_commit_warning(struct commit *old, struct commit *new)
{
struct rev_info revs;
- struct object *object = &commit->object;
+ struct object *object = &old->object;
struct object_array refs;
init_revisions(&revs, NULL);
add_pending_object(&revs, object, sha1_to_hex(object->sha1));
for_each_ref(add_pending_uninteresting_ref, &revs);
+ add_pending_sha1(&revs, "HEAD", new->object.sha1, UNINTERESTING);
refs = revs.pending;
revs.leak_pending = 1;
if (prepare_revision_walk(&revs))
die(_("internal error in revision walk"));
- if (!(commit->object.flags & UNINTERESTING))
- suggest_reattach(commit, &revs);
+ if (!(old->object.flags & UNINTERESTING))
+ suggest_reattach(old, &revs);
else
- describe_detached_head(_("Previous HEAD position was"), commit);
+ describe_detached_head(_("Previous HEAD position was"), old);
clear_commit_marks_for_object_array(&refs, ALL_REV_FLAGS);
free(refs.objects);
}
if (!opts->quiet && !old.path && old.commit && new->commit != old.commit)
- orphaned_commit_warning(old.commit);
+ orphaned_commit_warning(old.commit, new->commit);
update_refs_for_switch(opts, &old, new);
if (opts.writeout_stage)
die(_("--ours/--theirs is incompatible with switching branches."));
- if (!new.commit) {
+ if (!new.commit && opts.new_branch) {
unsigned char rev[20];
int flag;
opts.update = 1;
opts.merge = 1;
opts.fn = oneway_merge;
- opts.verbose_update = (option_verbosity > 0);
+ opts.verbose_update = (option_verbosity >= 0);
opts.src_index = &the_index;
opts.dst_index = &the_index;
#include "cache.h"
#include "parse-options.h"
#include "run-command.h"
+#include "argv-array.h"
#define FAILED_RUN "failed to run %s"
static int gc_auto_pack_limit = 50;
static const char *prune_expire = "2.weeks.ago";
-#define MAX_ADD 10
-static const char *argv_pack_refs[] = {"pack-refs", "--all", "--prune", NULL};
-static const char *argv_reflog[] = {"reflog", "expire", "--all", NULL};
-static const char *argv_repack[MAX_ADD] = {"repack", "-d", "-l", NULL};
-static const char *argv_prune[] = {"prune", "--expire", NULL, NULL, NULL};
-static const char *argv_rerere[] = {"rerere", "gc", NULL};
+static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
+static struct argv_array reflog = ARGV_ARRAY_INIT;
+static struct argv_array repack = ARGV_ARRAY_INIT;
+static struct argv_array prune = ARGV_ARRAY_INIT;
+static struct argv_array rerere = ARGV_ARRAY_INIT;
static int gc_config(const char *var, const char *value, void *cb)
{
return git_default_config(var, value, cb);
}
-static void append_option(const char **cmd, const char *opt, int max_length)
-{
- int i;
-
- for (i = 0; cmd[i]; i++)
- ;
-
- if (i + 2 >= max_length)
- die(_("Too many options specified"));
- cmd[i++] = opt;
- cmd[i] = NULL;
-}
-
static int too_many_loose_objects(void)
{
/*
return gc_auto_pack_limit <= cnt;
}
+static void add_repack_all_option(void)
+{
+ if (prune_expire && !strcmp(prune_expire, "now"))
+ argv_array_push(&repack, "-a");
+ else {
+ argv_array_push(&repack, "-A");
+ if (prune_expire)
+ argv_array_pushf(&repack, "--unpack-unreachable=%s", prune_expire);
+ }
+}
+
static int need_to_gc(void)
{
/*
* there is no need.
*/
if (too_many_packs())
- append_option(argv_repack,
- prune_expire && !strcmp(prune_expire, "now") ?
- "-a" : "-A",
- MAX_ADD);
+ add_repack_all_option();
else if (!too_many_loose_objects())
return 0;
int aggressive = 0;
int auto_gc = 0;
int quiet = 0;
- char buf[80];
struct option builtin_gc_options[] = {
OPT__QUIET(&quiet, "suppress progress reporting"),
if (argc == 2 && !strcmp(argv[1], "-h"))
usage_with_options(builtin_gc_usage, builtin_gc_options);
+ argv_array_pushl(&pack_refs_cmd, "pack-refs", "--all", "--prune", NULL);
+ argv_array_pushl(&reflog, "reflog", "expire", "--all", NULL);
+ argv_array_pushl(&repack, "repack", "-d", "-l", NULL);
+ argv_array_pushl(&prune, "prune", "--expire", NULL );
+ argv_array_pushl(&rerere, "rerere", "gc", NULL);
+
git_config(gc_config, NULL);
if (pack_refs < 0)
usage_with_options(builtin_gc_usage, builtin_gc_options);
if (aggressive) {
- append_option(argv_repack, "-f", MAX_ADD);
- append_option(argv_repack, "--depth=250", MAX_ADD);
- if (aggressive_window > 0) {
- sprintf(buf, "--window=%d", aggressive_window);
- append_option(argv_repack, buf, MAX_ADD);
- }
+ argv_array_push(&repack, "-f");
+ argv_array_push(&repack, "--depth=250");
+ if (aggressive_window > 0)
+ argv_array_pushf(&repack, "--window=%d", aggressive_window);
}
if (quiet)
- append_option(argv_repack, "-q", MAX_ADD);
+ argv_array_push(&repack, "-q");
if (auto_gc) {
/*
"run \"git gc\" manually. See "
"\"git help gc\" for more information.\n"));
} else
- append_option(argv_repack,
- prune_expire && !strcmp(prune_expire, "now")
- ? "-a" : "-A",
- MAX_ADD);
+ add_repack_all_option();
- if (pack_refs && run_command_v_opt(argv_pack_refs, RUN_GIT_CMD))
- return error(FAILED_RUN, argv_pack_refs[0]);
+ if (pack_refs && run_command_v_opt(pack_refs_cmd.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, pack_refs_cmd.argv[0]);
- if (run_command_v_opt(argv_reflog, RUN_GIT_CMD))
- return error(FAILED_RUN, argv_reflog[0]);
+ if (run_command_v_opt(reflog.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, reflog.argv[0]);
- if (run_command_v_opt(argv_repack, RUN_GIT_CMD))
- return error(FAILED_RUN, argv_repack[0]);
+ if (run_command_v_opt(repack.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, repack.argv[0]);
if (prune_expire) {
- argv_prune[2] = prune_expire;
+ argv_array_push(&prune, prune_expire);
if (quiet)
- argv_prune[3] = "--no-progress";
- if (run_command_v_opt(argv_prune, RUN_GIT_CMD))
- return error(FAILED_RUN, argv_prune[0]);
+ argv_array_push(&prune, "--no-progress");
+ if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, prune.argv[0]);
}
- if (run_command_v_opt(argv_rerere, RUN_GIT_CMD))
- return error(FAILED_RUN, argv_rerere[0]);
+ if (run_command_v_opt(rerere.argv, RUN_GIT_CMD))
+ return error(FAILED_RUN, rerere.argv[0]);
if (auto_gc && too_many_loose_objects())
warning(_("There are too many unreachable loose objects; "
static int non_empty;
static int reuse_delta = 1, reuse_object = 1;
static int keep_unreachable, unpack_unreachable, include_tag;
+static unsigned long unpack_unreachable_expiration;
static int local;
static int incremental;
static int ignore_packed_keep;
if (!p->pack_local || p->pack_keep)
continue;
+ if (unpack_unreachable_expiration &&
+ p->mtime < unpack_unreachable_expiration)
+ continue;
+
if (open_pack_index(p))
die("cannot open pack index");
return 0;
}
+static int option_parse_unpack_unreachable(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset) {
+ unpack_unreachable = 0;
+ unpack_unreachable_expiration = 0;
+ }
+ else {
+ unpack_unreachable = 1;
+ if (arg)
+ unpack_unreachable_expiration = approxidate(arg);
+ }
+ return 0;
+}
+
static int option_parse_ulong(const struct option *opt,
const char *arg, int unset)
{
"include tag objects that refer to objects to be packed"),
OPT_BOOL(0, "keep-unreachable", &keep_unreachable,
"keep unreachable objects"),
- OPT_BOOL(0, "unpack-unreachable", &unpack_unreachable,
- "unpack unreachable objects"),
+ { OPTION_CALLBACK, 0, "unpack-unreachable", NULL, "time",
+ "unpack unreachable objects newer than <time>",
+ PARSE_OPT_OPTARG, option_parse_unpack_unreachable },
OPT_BOOL(0, "thin", &thin,
"create thin packs"),
OPT_BOOL(0, "honor-pack-keep", &ignore_packed_keep,
static const char **refspec;
static int refspec_nr;
static int refspec_alloc;
+static int default_matching_used;
static void add_refspec(const char *ref)
{
{
switch (push_default) {
default:
+ case PUSH_DEFAULT_UNSPECIFIED:
+ default_matching_used = 1;
+ /* fallthru */
case PUSH_DEFAULT_MATCHING:
add_refspec(":");
break;
}
}
+static const char message_advice_pull_before_push[] =
+ N_("Updates were rejected because the tip of your current branch is behind\n"
+ "its remote counterpart. Merge the remote changes (e.g. 'git pull')\n"
+ "before pushing again.\n"
+ "See the 'Note about fast-forwards' in 'git push --help' for details.");
+
+static const char message_advice_use_upstream[] =
+ N_("Updates were rejected because a pushed branch tip is behind its remote\n"
+ "counterpart. If you did not intend to push that branch, you may want to\n"
+ "specify branches to push or set the 'push.default' configuration\n"
+ "variable to 'current' or 'upstream' to push only the current branch.");
+
+static const char message_advice_checkout_pull_push[] =
+ N_("Updates were rejected because a pushed branch tip is behind its remote\n"
+ "counterpart. Check out this branch and merge the remote changes\n"
+ "(e.g. 'git pull') before pushing again.\n"
+ "See the 'Note about fast-forwards' in 'git push --help' for details.");
+
+static void advise_pull_before_push(void)
+{
+ if (!advice_push_non_ff_current || !advice_push_nonfastforward)
+ return;
+ advise(_(message_advice_pull_before_push));
+}
+
+static void advise_use_upstream(void)
+{
+ if (!advice_push_non_ff_default || !advice_push_nonfastforward)
+ return;
+ advise(_(message_advice_use_upstream));
+}
+
+static void advise_checkout_pull_push(void)
+{
+ if (!advice_push_non_ff_matching || !advice_push_nonfastforward)
+ return;
+ advise(_(message_advice_checkout_pull_push));
+}
+
static int push_with_options(struct transport *transport, int flags)
{
int err;
error(_("failed to push some refs to '%s'"), transport->url);
err |= transport_disconnect(transport);
-
if (!err)
return 0;
- if (nonfastforward && advice_push_nonfastforward) {
- fprintf(stderr, _("To prevent you from losing history, non-fast-forward updates were rejected\n"
- "Merge the remote changes (e.g. 'git pull') before pushing again. See the\n"
- "'Note about fast-forwards' section of 'git push --help' for details.\n"));
+ switch (nonfastforward) {
+ default:
+ break;
+ case NON_FF_HEAD:
+ advise_pull_before_push();
+ break;
+ case NON_FF_OTHER:
+ if (default_matching_used)
+ advise_use_upstream();
+ else
+ advise_checkout_pull_push();
+ break;
}
return 1;
struct pretty_print_context ctx = {0};
ctx.abbrev = revs->abbrev;
ctx.date_mode = revs->date_mode;
+ ctx.date_mode_explicit = revs->date_mode_explicit;
ctx.fmt = revs->commit_format;
pretty_print_commit(&ctx, commit, &buf);
if (revs->graph) {
if (!strcmp(arg, "--show-prefix")) {
if (prefix)
puts(prefix);
+ else
+ putchar('\n');
continue;
}
if (!strcmp(arg, "--show-cdup")) {
break;
}
}
+ va_end(ap);
if (opt1 && opt2)
die(_("%s: %s cannot be used with %s"), me, opt1, opt2);
const char *receivepack = "git-receive-pack";
int flags;
int nonfastforward = 0;
+ int progress = -1;
argv++;
for (i = 1; i < argc; i++, argv++) {
args.verbose = 1;
continue;
}
+ if (!strcmp(arg, "--progress")) {
+ progress = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--no-progress")) {
+ progress = 0;
+ continue;
+ }
if (!strcmp(arg, "--thin")) {
args.use_thin_pack = 1;
continue;
}
}
+ if (progress == -1)
+ progress = !args.quiet && isatty(2);
+ args.progress = progress;
+
if (args.stateless_rpc) {
conn = NULL;
fd[0] = 0;
PUSH_DEFAULT_NOTHING = 0,
PUSH_DEFAULT_MATCHING,
PUSH_DEFAULT_UPSTREAM,
- PUSH_DEFAULT_CURRENT
+ PUSH_DEFAULT_CURRENT,
+ PUSH_DEFAULT_UNSPECIFIED
};
extern enum branch_track git_branch_track;
const char *after_subject;
int preserve_subject;
enum date_mode date_mode;
+ unsigned date_mode_explicit:1;
int need_8bit_cte;
int show_notes;
struct reflog_walk_info *reflog_info;
{
int ret = 0;
struct strbuf buf = STRBUF_INIT;
+ char *expanded = expand_user_path(path);
+
+ if (!expanded)
+ return error("Could not expand include path '%s'", path);
+ path = expanded;
/*
* Use an absolute path as-is, but interpret relative paths
inc->depth--;
}
strbuf_release(&buf);
+ free(expanded);
return ret;
}
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
-. git-sh-setup
+. $(git --exec-path)/git-sh-setup
require_work_tree
cd_to_toplevel
*/
if (options->stat_width == -1)
- width = term_columns();
+ width = term_columns() - options->output_prefix_length;
else
width = options->stat_width ? options->stat_width : 80;
* Adjust adjustable widths not to exceed maximum width
*/
if (name_width + number_width + 6 + graph_width > width) {
- if (graph_width > width * 3/8 - number_width - 6)
+ if (graph_width > width * 3/8 - number_width - 6) {
graph_width = width * 3/8 - number_width - 6;
+ if (graph_width < 6)
+ graph_width = 6;
+ }
+
if (options->stat_graph_width &&
graph_width > options->stat_graph_width)
graph_width = options->stat_graph_width;
else if (!strcmp(arg, "--ignore-space-at-eol"))
DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL);
else if (!strcmp(arg, "--patience"))
- DIFF_XDL_SET(options, PATIENCE_DIFF);
+ options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF);
else if (!strcmp(arg, "--histogram"))
- DIFF_XDL_SET(options, HISTOGRAM_DIFF);
+ options->xdl_opts = DIFF_WITH_ALG(options, HISTOGRAM_DIFF);
/* flags options */
else if (!strcmp(arg, "--binary")) {
#define DIFF_XDL_SET(opts, flag) ((opts)->xdl_opts |= XDF_##flag)
#define DIFF_XDL_CLR(opts, flag) ((opts)->xdl_opts &= ~XDF_##flag)
+#define DIFF_WITH_ALG(opts, flag) (((opts)->xdl_opts & ~XDF_DIFF_ALGORITHM_MASK) | XDF_##flag)
+
enum diff_words_type {
DIFF_WORDS_NONE = 0,
DIFF_WORDS_PORCELAIN,
diff_format_fn_t format_callback;
void *format_callback_data;
diff_prefix_fn_t output_prefix;
+ int output_prefix_length;
void *output_prefix_data;
};
unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
-enum push_default_type push_default = PUSH_DEFAULT_MATCHING;
+enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
#ifndef OBJECT_CREATION_MODE
#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
#endif
# 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.
#
n do not run git-update-server-info
q,quiet be quiet
l pass --local to git-pack-objects
+unpack-unreachable= with -A, do not loosen objects older than this
Packing constraints
window= size of the window used for delta compression
window-memory= same as the above, but limit memory size instead of entries count
-a) all_into_one=t ;;
-A) all_into_one=t
unpack_unreachable=--unpack-unreachable ;;
+ --unpack-unreachable)
+ unpack_unreachable="--unpack-unreachable=$2"; shift ;;
-d) remove_redundant=t ;;
-q) GIT_QUIET=t ;;
-f) no_reuse=--no-reuse-delta ;;
if test -n "$existing" -a -n "$unpack_unreachable" -a \
-n "$remove_redundant"
then
- args="$args $unpack_unreachable"
+ # This may have arbitrary user arguments, so we
+ # have to protect it against whitespace splitting
+ # when it gets run as "pack-objects $args" later.
+ # Fortunately, we know it's an approxidate, so we
+ # can just use dots instead.
+ args="$args $(echo "$unpack_unreachable" | tr ' ' .)"
fi
fi
;;
a=${a%/}
b=${b%/}
- rel=$(echo $b | sed -e 's|[^/]*|..|g')
+ # Turn each leading "*/" component into "../"
+ rel=$(echo $b | sed -e 's|[^/][^/]*|..|g')
echo "gitdir: $rel/$a" >"$path/.git"
- rel=$(echo $a | sed -e 's|[^/]*|..|g')
+ rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
(clear_local_git_env; cd "$path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
}
struct git_graph *graph = data;
static struct strbuf msgbuf = STRBUF_INIT;
+ assert(opt);
assert(graph);
+ opt->output_prefix_length = graph->width;
strbuf_reset(&msgbuf);
graph_padding_line(graph, &msgbuf);
return &msgbuf;
*/
opt->diffopt.output_prefix = diff_output_prefix_callback;
opt->diffopt.output_prefix_data = graph;
+ opt->diffopt.output_prefix_length = 0;
return graph;
}
if (!opt->header_list)
return NULL;
- p = opt->header_list;
+
for (p = opt->header_list; p; p = p->next) {
if (p->token != GREP_PATTERN_HEAD)
die("bug: a non-header pattern in grep header list.");
#include "run-command.h"
#include "string-list.h"
#include "url.h"
+#include "argv-array.h"
static const char content_type[] = "Content-Type";
static const char content_length[] = "Content-Length";
const char *encoding = getenv("HTTP_CONTENT_ENCODING");
const char *user = getenv("REMOTE_USER");
const char *host = getenv("REMOTE_ADDR");
- char *env[3];
- struct strbuf buf = STRBUF_INIT;
+ struct argv_array env = ARGV_ARRAY_INIT;
int gzipped_request = 0;
struct child_process cld;
if (!host || !*host)
host = "(none)";
- memset(&env, 0, sizeof(env));
- strbuf_addf(&buf, "GIT_COMMITTER_NAME=%s", user);
- env[0] = strbuf_detach(&buf, NULL);
-
- strbuf_addf(&buf, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host);
- env[1] = strbuf_detach(&buf, NULL);
- env[2] = NULL;
+ if (!getenv("GIT_COMMITTER_NAME"))
+ argv_array_pushf(&env, "GIT_COMMITTER_NAME=%s", user);
+ if (!getenv("GIT_COMMITTER_EMAIL"))
+ argv_array_pushf(&env, "GIT_COMMITTER_EMAIL=%s@http.%s",
+ user, host);
memset(&cld, 0, sizeof(cld));
cld.argv = argv;
- cld.env = (const char *const *)env;
+ cld.env = env.argv;
if (gzipped_request)
cld.in = -1;
cld.git_cmd = 1;
if (finish_command(&cld))
exit(1);
- free(env[0]);
- free(env[1]);
- strbuf_release(&buf);
+ argv_array_clear(&env);
}
static int show_text_ref(const char *name, const unsigned char *sha1,
* graph info here.
*/
show_reflog_message(opt->reflog_info,
- opt->commit_format == CMIT_FMT_ONELINE,
- opt->date_mode_explicit ?
- opt->date_mode :
- DATE_NORMAL);
+ opt->commit_format == CMIT_FMT_ONELINE,
+ opt->date_mode,
+ opt->date_mode_explicit);
if (opt->commit_format == CMIT_FMT_ONELINE)
return;
}
if (ctx.need_8bit_cte >= 0)
ctx.need_8bit_cte = has_non_ascii(opt->add_signoff);
ctx.date_mode = opt->date_mode;
+ ctx.date_mode_explicit = opt->date_mode_explicit;
ctx.abbrev = opt->diffopt.abbrev;
ctx.after_subject = extra_headers;
ctx.preserve_subject = opt->preserve_subject;
if (opt->use_terminator) {
if (!opt->missing_newline)
graph_show_padding(opt->graph);
- putchar('\n');
+ putchar(opt->diffopt.line_termination);
}
strbuf_release(&msgbuf);
else if (!prefixcmp(s, "subtree="))
o->subtree_shift = s + strlen("subtree=");
else if (!strcmp(s, "patience"))
- o->xdl_opts |= XDF_PATIENCE_DIFF;
+ o->xdl_opts = DIFF_WITH_ALG(o, PATIENCE_DIFF);
else if (!strcmp(s, "histogram"))
- o->xdl_opts |= XDF_HISTOGRAM_DIFF;
+ o->xdl_opts = DIFF_WITH_ALG(o, HISTOGRAM_DIFF);
else if (!strcmp(s, "ignore-space-change"))
o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(s, "ignore-all-space"))
get_reflog_selector(sb,
c->pretty_ctx->reflog_info,
c->pretty_ctx->date_mode,
+ c->pretty_ctx->date_mode_explicit,
(placeholder[1] == 'd'));
return 2;
case 's': /* reflog message */
}
struct commit_reflog {
- int flag, recno;
+ int recno;
+ enum selector_type {
+ SELECTOR_NONE,
+ SELECTOR_INDEX,
+ SELECTOR_DATE
+ } selector;
struct complete_reflogs *reflogs;
};
struct complete_reflogs *reflogs;
char *branch, *at = strchr(name, '@');
struct commit_reflog *commit_reflog;
+ enum selector_type selector = SELECTOR_NONE;
if (commit->object.flags & UNINTERESTING)
die ("Cannot walk reflogs for %s", name);
if (*ep != '}') {
recno = -1;
timestamp = approxidate(at + 2);
+ selector = SELECTOR_DATE;
}
+ else
+ selector = SELECTOR_INDEX;
} else
recno = 0;
commit_reflog = xcalloc(sizeof(struct commit_reflog), 1);
if (recno < 0) {
- commit_reflog->flag = 1;
commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);
if (commit_reflog->recno < 0) {
free(branch);
}
} else
commit_reflog->recno = reflogs->nr - recno - 1;
+ commit_reflog->selector = selector;
commit_reflog->reflogs = reflogs;
add_commit_info(commit, commit_reflog, &info->reflogs);
void get_reflog_selector(struct strbuf *sb,
struct reflog_walk_info *reflog_info,
- enum date_mode dmode,
+ enum date_mode dmode, int force_date,
int shorten)
{
struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
}
strbuf_addf(sb, "%s@{", printed_ref);
- if (commit_reflog->flag || dmode) {
+ if (commit_reflog->selector == SELECTOR_DATE ||
+ (commit_reflog->selector == SELECTOR_NONE && force_date)) {
info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
strbuf_addstr(sb, show_date(info->timestamp, info->tz, dmode));
} else {
}
void show_reflog_message(struct reflog_walk_info *reflog_info, int oneline,
- enum date_mode dmode)
+ enum date_mode dmode, int force_date)
{
if (reflog_info && reflog_info->last_commit_reflog) {
struct commit_reflog *commit_reflog = reflog_info->last_commit_reflog;
struct strbuf selector = STRBUF_INIT;
info = &commit_reflog->reflogs->items[commit_reflog->recno+1];
- get_reflog_selector(&selector, reflog_info, dmode, 0);
+ get_reflog_selector(&selector, reflog_info, dmode, force_date, 0);
if (oneline) {
printf("%s: %s", selector.buf, info->message);
}
extern void fake_reflog_parent(struct reflog_walk_info *info,
struct commit *commit);
extern void show_reflog_message(struct reflog_walk_info *info, int,
- enum date_mode);
+ enum date_mode, int force_date);
extern void get_reflog_message(struct strbuf *sb,
struct reflog_walk_info *reflog_info);
extern const char *get_reflog_ident(struct reflog_walk_info *reflog_info);
extern void get_reflog_selector(struct strbuf *sb,
struct reflog_walk_info *reflog_info,
- enum date_mode dmode,
+ enum date_mode dmode, int force_date,
int shorten);
#endif
argv[argc++] = "--quiet";
else if (options.verbosity > 1)
argv[argc++] = "--verbose";
+ argv[argc++] = options.progress ? "--progress" : "--no-progress";
argv[argc++] = url;
for (i = 0; i < nr_spec; i++)
argv[argc++] = specs[i];
'
test_expect_success 'non-fast-forward push shows help message' '
- test_i18ngrep "To prevent you from losing history, non-fast-forward updates were rejected" output
+ test_i18ngrep "Updates were rejected because" output
'
}
<Location /smart_noexport/>
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
</Location>
+<Location /smart_custom_env/>
+ SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+ SetEnv GIT_HTTP_EXPORT_ALL
+ SetEnv GIT_COMMITTER_NAME "Custom User"
+ SetEnv GIT_COMMITTER_EMAIL custom@example.com
+</Location>
ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/
ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/
+ScriptAlias /smart_custom_env/ ${GIT_EXEC_PATH}/git-http-backend/
<Directory ${GIT_EXEC_PATH}>
Options None
</Directory>
test_cmp expect actual
'
+test_expect_success 'include paths get tilde-expansion' '
+ echo "[test]one = 1" >one &&
+ echo "[include]path = ~/one" >.gitconfig &&
+ echo 1 >expect &&
+ git config test.one >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'include options can still be examined' '
echo "[test]one = 1" >one &&
echo "[include]path = one" >.gitconfig &&
check_fsck &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 4
+ test_line_count = 4 .git/logs/refs/heads/master
'
test_expect_success rewind '
check_have A B C D E F G H I J K L &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 5
+ test_line_count = 5 .git/logs/refs/heads/master
'
test_expect_success 'corrupt and check' '
--stale-fix \
--all &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 5 &&
+ test_line_count = 5 .git/logs/refs/heads/master &&
check_fsck "missing blob $F"
'
--stale-fix \
--all &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 2 &&
+ test_line_count = 2 .git/logs/refs/heads/master &&
check_fsck "dangling commit $K"
'
test_expect_success 'rewind2' '
test_tick && git reset --hard HEAD~2 &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 4
-
+ test_line_count = 4 .git/logs/refs/heads/master
'
test_expect_success '--expire=never' '
--expire=never \
--expire-unreachable=never \
--all &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 4
-
+ test_line_count = 4 .git/logs/refs/heads/master
'
test_expect_success 'gc.reflogexpire=never' '
git config gc.reflogexpire never &&
git config gc.reflogexpireunreachable never &&
git reflog expire --verbose --all &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 4
+ test_line_count = 4 .git/logs/refs/heads/master
'
test_expect_success 'gc.reflogexpire=false' '
git config gc.reflogexpire false &&
git config gc.reflogexpireunreachable false &&
git reflog expire --verbose --all &&
- loglen=$(wc -l <.git/logs/refs/heads/master) &&
- test $loglen = 4 &&
+ test_line_count = 4 .git/logs/refs/heads/master &&
git config --unset gc.reflogexpire &&
git config --unset gc.reflogexpireunreachable
'
cat >expect <<'EOF'
-Reflog: HEAD@{1112911993 -0700} (C O Mitter <committer@example.com>)
+HEAD@{Thu Apr 7 15:13:13 2005 -0700}
+EOF
+test_expect_success 'using @{now} syntax shows reflog date (format=%gd)' '
+ git log -g -1 --format=%gd HEAD@{now} >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{Thu Apr 7 15:13:13 2005 -0700} (C O Mitter <committer@example.com>)
Reflog message: commit (initial): one
EOF
test_expect_success 'using --date= shows reflog date (multiline)' '
- git log -g -1 --date=raw >tmp &&
+ git log -g -1 --date=default >tmp &&
grep ^Reflog <tmp >actual &&
test_cmp expect actual
'
cat >expect <<'EOF'
-e46513e HEAD@{1112911993 -0700}: commit (initial): one
+e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
EOF
test_expect_success 'using --date= shows reflog date (oneline)' '
- git log -g -1 --oneline --date=raw >actual &&
+ git log -g -1 --oneline --date=default >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{1112911993 -0700}
+EOF
+test_expect_success 'using --date= shows reflog date (format=%gd)' '
+ git log -g -1 --format=%gd --date=raw >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
+Reflog message: commit (initial): one
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (multiline)' '
+ test_config log.date raw &&
+ git log -g -1 >tmp &&
+ grep ^Reflog <tmp >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+e46513e HEAD@{0}: commit (initial): one
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (oneline)' '
+ test_config log.date raw &&
+ git log -g -1 --oneline >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{0}
+EOF
+test_expect_success 'log.date does not invoke "--date" magic (format=%gd)' '
+ test_config log.date raw &&
+ git log -g -1 --format=%gd >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+HEAD@{0}
+EOF
+test_expect_success '--date magic does not override explicit @{0} syntax' '
+ git log -g -1 --format=%gd --date=raw HEAD@{0} >actual &&
test_cmp expect actual
'
)
'
-test_expect_failure 'empty prefix is actually written out' '
+test_expect_success 'empty prefix is actually written out' '
echo >expected &&
(
cd work &&
rm -f path* .merge_* out .git/index &&
git read-tree $t1 &&
git checkout-index --temp -- path1 >out &&
-test $(wc -l <out) = 1 &&
+test_line_count = 1 out &&
test $(cut "-d " -f2 out) = path1 &&
p=$(cut "-d " -f1 out) &&
test -f $p &&
rm -f path* .merge_* out .git/index &&
git read-tree $t1 &&
git checkout-index -a --temp >out &&
-test $(wc -l <out) = 5 &&
+test_line_count = 5 out &&
for f in path0 path1 path3 path4 asubdir/path5
do
test $(grep $f out | cut "-d " -f2) = $f &&
'checkout one stage 2 to temporary file' '
rm -f path* .merge_* out &&
git checkout-index --stage=2 --temp -- path1 >out &&
-test $(wc -l <out) = 1 &&
+test_line_count = 1 out &&
test $(cut "-d " -f2 out) = path1 &&
p=$(cut "-d " -f1 out) &&
test -f $p &&
'checkout all stage 2 to temporary files' '
rm -f path* .merge_* out &&
git checkout-index --all --stage=2 --temp >out &&
-test $(wc -l <out) = 3 &&
+test_line_count = 3 out &&
for f in path1 path2 path4
do
test $(grep $f out | cut "-d " -f2) = $f &&
'checkout all stages/one file to nothing' '
rm -f path* .merge_* out &&
git checkout-index --stage=all --temp -- path0 >out &&
-test $(wc -l <out) = 0'
+test_line_count = 0 out'
test_expect_success \
'checkout all stages/one file to temporary files' '
rm -f path* .merge_* out &&
git checkout-index --stage=all --temp -- path1 >out &&
-test $(wc -l <out) = 1 &&
+test_line_count = 1 out &&
test $(cut "-d " -f2 out) = path1 &&
cut "-d " -f1 out | (read s1 s2 s3 &&
test -f $s1 &&
'checkout some stages/one file to temporary files' '
rm -f path* .merge_* out &&
git checkout-index --stage=all --temp -- path2 >out &&
-test $(wc -l <out) = 1 &&
+test_line_count = 1 out &&
test $(cut "-d " -f2 out) = path2 &&
cut "-d " -f1 out | (read s1 s2 s3 &&
test $s1 = . &&
'checkout all stages/all files to temporary files' '
rm -f path* .merge_* out &&
git checkout-index -a --stage=all --temp >out &&
-test $(wc -l <out) = 5'
+test_line_count = 5 out'
test_expect_success \
'-- path0: no entry' '
'checkout --temp within subdir' '
(cd asubdir &&
git checkout-index -a --stage=all >out &&
- test $(wc -l <out) = 1 &&
+ test_line_count = 1 out &&
test $(grep path5 out | cut "-d " -f2) = path5 &&
grep path5 out | cut "-d " -f1 | (read s1 s2 s3 &&
test -f ../$s1 &&
rm -f .git/index &&
git read-tree $t4 &&
git checkout-index --temp -a >out &&
-test $(wc -l <out) = 1 &&
+test_line_count = 1 out &&
test $(cut "-d " -f2 out) = a &&
p=$(cut "-d " -f1 out) &&
test -f $p &&
test_cmp expect actual
'
+test_expect_success 'checking out in a newly created repo' '
+ test_create_repo empty &&
+ (
+ cd empty &&
+ git symbolic-ref HEAD >expect &&
+ test_must_fail git checkout &&
+ git symbolic-ref HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
git symbolic-ref -q HEAD >/dev/null
}
-ORPHAN_WARNING='you are leaving .* commit.*behind'
PREV_HEAD_DESC='Previous HEAD position was'
check_orphan_warning() {
- test_i18ngrep "$ORPHAN_WARNING" "$1" &&
+ test_i18ngrep "you are leaving $2 behind" "$1" &&
test_i18ngrep ! "$PREV_HEAD_DESC" "$1"
}
check_no_orphan_warning() {
- test_i18ngrep ! "$ORPHAN_WARNING" "$1" &&
+ test_i18ngrep ! "you are leaving .* commit.*behind" "$1" &&
test_i18ngrep "$PREV_HEAD_DESC" "$1"
}
git checkout --detach two &&
echo content >orphan &&
git add orphan &&
- git commit -a -m orphan &&
+ git commit -a -m orphan1 &&
+ echo new content >orphan &&
+ git commit -a -m orphan2 &&
+ orphan2=$(git rev-parse HEAD) &&
git checkout master 2>stderr
'
test_expect_success 'checkout warns on orphan commits: output' '
- check_orphan_warning stderr
+ check_orphan_warning stderr "2 commits"
+'
+
+test_expect_success 'checkout warns orphaning 1 of 2 commits' '
+ git checkout "$orphan2" &&
+ git checkout HEAD^ 2>stderr
+'
+
+test_expect_success 'checkout warns orphaning 1 of 2 commits: output' '
+ check_orphan_warning stderr "1 commit"
'
test_expect_success 'checkout does not warn leaving ref tip' '
prime_resolve_undo &&
git update-index --unresolve fi/le &&
git ls-files -u >actual &&
- test $(wc -l <actual) = 3
+ test_line_count = 3 actual
'
test_expect_success 'rerere and rerere forget' '
test_tick &&
git rebase $2 -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual) &&
+ test_line_count = 3 actual &&
git diff --exit-code $1 &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 1 = $(git cat-file commit HEAD^ | grep first | wc -l)
test_tick &&
git rebase $2 -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual) &&
+ test_line_count = 3 actual &&
git diff --exit-code $1 &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 2 = $(git cat-file commit HEAD^ | grep first | wc -l)
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
- test 4 = $(wc -l <actual) &&
+ test_line_count = 4 actual &&
git diff --exit-code final-missquash &&
test 0 = $(git rev-list final-missquash...HEAD | wc -l)
'
test_tick &&
git rebase --autosquash -i HEAD~4 &&
git log --oneline >actual &&
- test 4 = $(wc -l <actual) &&
+ test_line_count = 4 actual &&
git diff --exit-code final-multisquash &&
test 1 = "$(git cat-file blob HEAD^^:file1)" &&
test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) &&
test_tick &&
git rebase --autosquash -i HEAD~4 &&
git log --oneline >actual &&
- test 5 = $(wc -l <actual) &&
+ test_line_count = 5 actual &&
git diff --exit-code final-presquash &&
test 0 = "$(git cat-file blob HEAD^^:file1)" &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual) &&
+ test_line_count = 3 actual &&
git diff --exit-code final-shasquash &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual) &&
+ test_line_count = 3 actual &&
git diff --exit-code final-longshasquash &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l)
test_tick &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual) &&
+ test_line_count = 3 actual &&
git diff --exit-code final-commit-$1 &&
test 1 = "$(git cat-file blob HEAD^:file1)" &&
test $2 = $(git cat-file commit HEAD^ | grep first | wc -l)
git config --unset-all i18n.commitencoding &&
git rebase --autosquash -i HEAD^^^ &&
git log --oneline >actual &&
- test 3 = $(wc -l <actual)
+ test_line_count = 3 actual
'
}
test_expect_success 'git diff-tree HEAD^ HEAD' '
git diff-tree --quiet HEAD^ HEAD >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
'
test_expect_success 'git diff-tree HEAD^ HEAD -- a' '
git diff-tree --quiet HEAD^ HEAD -- a >cnt
- test $? = 0 && test $(wc -l <cnt) = 0
+ test $? = 0 && test_line_count = 0 cnt
'
test_expect_success 'git diff-tree HEAD^ HEAD -- b' '
git diff-tree --quiet HEAD^ HEAD -- b >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
'
# this diff outputs one line: sha1 of the given head
test_expect_success 'echo HEAD | git diff-tree --stdin' '
echo $(git rev-parse HEAD) | git diff-tree --quiet --stdin >cnt
- test $? = 1 && test $(wc -l <cnt) = 1
+ test $? = 1 && test_line_count = 1 cnt
'
test_expect_success 'git diff-tree HEAD HEAD' '
git diff-tree --quiet HEAD HEAD >cnt
- test $? = 0 && test $(wc -l <cnt) = 0
+ test $? = 0 && test_line_count = 0 cnt
'
test_expect_success 'git diff-files' '
git diff-files --quiet >cnt
- test $? = 0 && test $(wc -l <cnt) = 0
+ test $? = 0 && test_line_count = 0 cnt
'
test_expect_success 'git diff-index --cached HEAD' '
git diff-index --quiet --cached HEAD >cnt
- test $? = 0 && test $(wc -l <cnt) = 0
+ test $? = 0 && test_line_count = 0 cnt
'
test_expect_success 'git diff-index --cached HEAD^' '
git diff-index --quiet --cached HEAD^ >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
'
test_expect_success 'git diff-index --cached HEAD^' '
echo text >>b &&
echo 3 >c &&
git add . && {
git diff-index --quiet --cached HEAD^ >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
}
'
test_expect_success 'git diff-tree -Stext HEAD^ HEAD -- b' '
git commit -m "text in b" && {
git diff-tree --quiet -Stext HEAD^ HEAD -- b >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
}
'
test_expect_success 'git diff-tree -Snot-found HEAD^ HEAD -- b' '
git diff-tree --quiet -Snot-found HEAD^ HEAD -- b >cnt
- test $? = 0 && test $(wc -l <cnt) = 0
+ test $? = 0 && test_line_count = 0 cnt
'
test_expect_success 'git diff-files' '
echo 3 >>c && {
git diff-files --quiet >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
}
'
test_expect_success 'git diff-index --cached HEAD' '
git update-index c && {
git diff-index --quiet --cached HEAD >cnt
- test $? = 1 && test $(wc -l <cnt) = 0
+ test $? = 1 && test_line_count = 0 cnt
}
'
cat >expect80 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
-
+cat >expect80-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
cat >expect200 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
-
+cat >expect200-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb COLUMNS (big change)" '
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb COLUMNS (big change)" '
+ COLUMNS=200 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect200 diff HEAD^ HEAD --stat
cat >expect40 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++
EOF
-
+cat >expect40-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb not enough COLUMNS (big change)" '
test_cmp "$expect" actual
'
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb not enough COLUMNS (big change)" '
+ COLUMNS=40 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect40 diff HEAD^ HEAD --stat
+respects expect40 show --stat
+respects expect40 log -1 --stat
+EOF
+
+cat >expect40 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++
+EOF
+cat >expect40-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++
+EOF
+while read verb expect cmd args
+do
test_expect_success "$cmd $verb statGraphWidth config" '
git -c diff.statGraphWidth=26 $cmd $args >output
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb statGraphWidth config" '
+ git -c diff.statGraphWidth=26 $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect40 diff HEAD^ HEAD --stat
cat >expect <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++
EOF
+cat >expect-graph <<'EOF'
+| abcd | 1000 ++++++++++++++++++++++++++
+EOF
while read cmd args
do
test_expect_success "$cmd --stat=width with big change" '
test_cmp expect actual
'
- test_expect_success "$cmd --stat-graph--width with big change" '
+ test_expect_success "$cmd --stat-graph-width with big change" '
git $cmd $args --stat-graph-width=26 >output
grep " | " output >actual &&
test_cmp expect actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --stat-width=width --graph with big change" '
+ git $cmd $args --stat-width=40 --graph >output
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
+
+ test_expect_success "$cmd --stat-graph-width --graph with big change" '
+ git $cmd $args --stat-graph-width=26 --graph >output
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
done <<\EOF
format-patch -1 --stdout
diff HEAD^ HEAD --stat
cat >expect <<'EOF'
...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
EOF
+cat >expect-graph <<'EOF'
+| ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++
+EOF
while read cmd args
do
test_expect_success "$cmd --stat=width with big change is more balanced" '
grep " | " output >actual &&
test_cmp expect actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --stat=width --graph with big change is balanced" '
+ git $cmd $args --stat-width=60 --graph >output &&
+ grep " | " output >actual &&
+ test_cmp expect-graph actual
+ '
done <<\EOF
format-patch -1 --stdout
diff HEAD^ HEAD --stat
cat >expect80 <<'EOF'
...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++++++++++
EOF
+cat >expect80-graph <<'EOF'
+| ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 ++++++++++++++++++++
+EOF
cat >expect200 <<'EOF'
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
+cat >expect200-graph <<'EOF'
+| aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1000 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
while read verb expect cmd args
do
test_expect_success "$cmd $verb COLUMNS (long filename)" '
grep " | " output >actual &&
test_cmp "$expect" actual
'
+
+ test "$cmd" != diff || continue
+
+ test_expect_success "$cmd --graph $verb COLUMNS (long filename)" '
+ COLUMNS=200 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
done <<\EOF
ignores expect80 format-patch -1 --stdout
respects expect200 diff HEAD^ HEAD --stat
respects expect200 log -1 --stat
EOF
+cat >expect1 <<'EOF'
+ ...aaaaaaa | 1000 ++++++
+EOF
+cat >expect1-graph <<'EOF'
+| ...aaaaaaa | 1000 ++++++
+EOF
+while read verb expect cmd args
+do
+ test_expect_success COLUMNS_CAN_BE_1 \
+ "$cmd $verb prefix greater than COLUMNS (big change)" '
+ COLUMNS=1 git $cmd $args >output
+ grep " | " output >actual &&
+ test_cmp "$expect" actual
+ '
+
+ test "$cmd" != diff || continue
+
+ test_expect_success COLUMNS_CAN_BE_1 \
+ "$cmd --graph $verb prefix greater than COLUMNS (big change)" '
+ COLUMNS=1 git $cmd $args --graph >output
+ grep " | " output >actual &&
+ test_cmp "$expect-graph" actual
+ '
+done <<\EOF
+ignores expect80 format-patch -1 --stdout
+respects expect1 diff HEAD^ HEAD --stat
+respects expect1 show --stat
+respects expect1 log -1 --stat
+EOF
+
cat >expect <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
test_must_fail git log --pretty=test-foo
'
+test_expect_success 'NUL separation' '
+ printf "add bar\0initial" >expected &&
+ git log -z --pretty="format:%s" >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'NUL termination' '
+ printf "add bar\0initial\0" >expected &&
+ git log -z --pretty="tformat:%s" >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'NUL separation with --stat' '
+ stat0_part=$(git diff --stat HEAD^ HEAD) &&
+ stat1_part=$(git diff --stat --root HEAD^) &&
+ printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n" >expected &&
+ git log -z --stat --pretty="format:%s" >actual &&
+ test_cmp expected actual
+'
+
+test_expect_failure 'NUL termination with --stat' '
+ stat0_part=$(git diff --stat HEAD^ HEAD) &&
+ stat1_part=$(git diff --stat --root HEAD^) &&
+ printf "add bar\n$stat0_part\n\0initial\n$stat1_part\n\0" >expected &&
+ git log -z --stat --pretty="tformat:%s" >actual &&
+ test_cmp expected actual
+'
+
test_done
git mailsplit -d3 -o. "$TEST_DIRECTORY"/t5100/nul-plain &&
test_cmp "$TEST_DIRECTORY"/t5100/nul-plain 001 &&
(cat 001 | git mailinfo msg patch) &&
- test 4 = $(wc -l < patch)
+ test_line_count = 4 patch
'
git clone --bare test_repo test_repo.git &&
cd test_repo.git &&
git config http.receivepack true &&
+ git config core.logallrefupdates true &&
ORIG_HEAD=$(git rev-parse --verify HEAD) &&
cd - &&
mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH"
'
test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper: our output' '
- test_i18ngrep "To prevent you from losing history, non-fast-forward updates were rejected" \
+ test_i18ngrep "Updates were rejected because" \
output
'
git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
'
-test_expect_success TTY 'quiet push' '
+test_expect_success TTY 'push shows progress when stderr is a tty' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit noisy &&
+ test_terminal git push >output 2>&1 &&
+ grep "^Writing objects" output
+'
+
+test_expect_success TTY 'push --quiet silences status and progress' '
cd "$ROOT_PATH"/test_repo_clone &&
test_commit quiet &&
- test_terminal git push --quiet --no-progress 2>&1 | tee output &&
+ test_terminal git push --quiet >output 2>&1 &&
test_cmp /dev/null output
'
+test_expect_success TTY 'push --no-progress silences progress but not status' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit no-progress &&
+ test_terminal git push --no-progress >output 2>&1 &&
+ grep "^To http" output &&
+ ! grep "^Writing objects"
+'
+
+test_expect_success 'push --progress shows progress to non-tty' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit progress &&
+ git push --progress >output 2>&1 &&
+ grep "^To http" output &&
+ grep "^Writing objects" output
+'
+
+test_expect_success 'http push gives sane defaults to reflog' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit reflog-test &&
+ git push "$HTTPD_URL"/smart/test_repo.git &&
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
+ log -g -1 --format="%gn <%ge>" >actual &&
+ echo "anonymous <anonymous@http.127.0.0.1>" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'http push respects GIT_COMMITTER_* in reflog' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit custom-reflog-test &&
+ git push "$HTTPD_URL"/smart_custom_env/test_repo.git &&
+ git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
+ log -g -1 --format="%gn <%ge>" >actual &&
+ echo "Custom User <custom@example.com>" >expect &&
+ test_cmp expect actual
+'
+
stop_httpd
test_done
cd "$base_dir"
test_expect_success 'existence of info/alternates' \
-'test `wc -l <C/.git/objects/info/alternates` = 2'
+'test_line_count = 2 C/.git/objects/info/alternates'
cd "$base_dir"
cd "$base_dir"
test_expect_success 'existence of info/alternates' \
-'test `wc -l <D/.git/objects/info/alternates` = 1'
+'test_line_count = 1 D/.git/objects/info/alternates'
cd "$base_dir"
test_valid_repo() {
git fsck --full > fsck.log &&
- test `wc -l < fsck.log` = 0
+ test_line_count = 0 fsck.log
}
base_dir=`pwd`
test_expect_success 'del LF before empty (1)' '
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD^^ >actual &&
- test $(wc -l <actual) = 2
+ test_line_count = 2 actual
'
test_expect_success 'del LF before empty (2)' '
git show -s --pretty=format:"%s%n%-b%nThanks%n" HEAD >actual &&
- test $(wc -l <actual) = 6 &&
+ test_line_count = 6 actual &&
grep "^$" actual
'
test_expect_success 'add LF before non-empty (1)' '
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD^^ >actual &&
- test $(wc -l <actual) = 2
+ test_line_count = 2 actual
'
test_expect_success 'add LF before non-empty (2)' '
git show -s --pretty=format:"%s%+b%nThanks%n" HEAD >actual &&
- test $(wc -l <actual) = 6 &&
+ test_line_count = 6 actual &&
grep "^$" actual
'
git commit -m "dummy" --allow-empty &&
git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. &&
git rev-list --oneline HEAD >test.txt &&
- test $(git rev-list --oneline HEAD | wc -l) -eq 5 &&
- test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5
+ test_line_count = 5 test.txt &&
+ git rev-list --oneline --graph HEAD >testg.txt &&
+ test_line_count = 5 testg.txt
'
test_done
git merge -m "merge HASH7 and SIDE_HASH7" "$HASH7" &&
B_HASH=$(git rev-parse --verify HEAD) &&
git merge-base --all "$A_HASH" "$B_HASH" > merge_bases.txt &&
- test $(wc -l < merge_bases.txt) = "2" &&
+ test_line_count = 2 merge_bases.txt &&
grep "$HASH5" merge_bases.txt &&
grep "$SIDE_HASH5" merge_bases.txt
'
test_expect_success 'massive simple rename does not spam added files' '
sane_unset GIT_MERGE_VERBOSITY &&
git merge --no-stat simple-rename | grep -v Removing >output &&
- test 5 -gt "$(wc -l < output)"
+ test_line_count -lt 5 output
'
test_done
test 0 -eq $(git ls-files -u | wc -l) &&
test 0 -eq $(git ls-files -o | wc -l) &&
- test 6 -eq $(wc -l < c) &&
+ test_line_count = 6 c &&
test $(git rev-parse HEAD:a) = $(git rev-parse B:a) &&
test $(git rev-parse HEAD:b) = $(git rev-parse A:b)
'
git checkout -f renamer && git clean -f &&
git checkout renamer^ 2>messages &&
test_i18ngrep "HEAD is now at 7329388" messages &&
- test 1 -eq $(wc -l <messages) &&
+ test_line_count = 1 messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
git checkout -f renamer && git clean -f &&
git checkout renamer^ 2>messages &&
test_i18ngrep "HEAD is now at 7329388" messages &&
- test 1 -lt $(wc -l <messages) &&
+ test_line_count -gt 1 messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
test_expect_success 'status should only print one line' '
git submodule status >lines &&
- test $(wc -l <lines) = 1
+ test_line_count = 1 lines
'
test_expect_success 'setup - fetch commit name from submodule' '
cd "$base_dir"
test_expect_success 'after add: existence of info/alternates' \
-'test `wc -l <super/.git/modules/sub/objects/info/alternates` = 1'
+'test_line_count = 1 super/.git/modules/sub/objects/info/alternates'
cd "$base_dir"
cd "$base_dir"
test_expect_success 'after update: existence of info/alternates' \
-'test `wc -l <super-clone/.git/modules/sub/objects/info/alternates` = 1'
+'test_line_count = 1 super-clone/.git/modules/sub/objects/info/alternates'
cd "$base_dir"
git reset --hard &&
git commit -s -m "hello: kitty" --allow-empty &&
git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
- test $(wc -l <actual) = 3
+ test_line_count = 3 actual
'
compare_mtimes < mtimes
'
+test_expect_success 'do not bother loosening old objects' '
+ obj1=$(echo one | git hash-object -w --stdin) &&
+ obj2=$(echo two | git hash-object -w --stdin) &&
+ pack1=$(echo $obj1 | git pack-objects .git/objects/pack/pack) &&
+ pack2=$(echo $obj2 | git pack-objects .git/objects/pack/pack) &&
+ git prune-packed &&
+ git cat-file -p $obj1 &&
+ git cat-file -p $obj2 &&
+ test-chmtime =-86400 .git/objects/pack/pack-$pack2.pack &&
+ git repack -A -d --unpack-unreachable=1.hour.ago &&
+ git cat-file -p $obj1 &&
+ test_must_fail git cat-file -p $obj2
+'
+
test_done
' - "$1"
}
+verify_packs () {
+ for p in .git/objects/pack/*.pack
+ do
+ git verify-pack "$@" "$p" || return
+ done
+}
+
file2_data='file2
second line of EOF'
'A: create pack from stdin' \
'git fast-import --export-marks=marks.out <input &&
git whatchanged master'
-test_expect_success \
- 'A: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'A: verify pack' '
+ verify_packs
+'
cat >expect <<EOF
author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
'A: verify marks import does not crash' \
'git fast-import --import-marks=marks.out <input &&
git whatchanged verify--import-marks'
-test_expect_success \
- 'A: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'A: verify pack' '
+ verify_packs
+'
+
cat >expect <<EOF
:000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2
EOF
'C: incremental import create pack from stdin' \
'git fast-import <input &&
git whatchanged branch'
-test_expect_success \
- 'C: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'C: verify pack' '
+ verify_packs
+'
+
test_expect_success \
'C: validate reuse existing blob' \
'test $newf = `git rev-parse --verify branch:file2/newf` &&
'D: inline data in commit' \
'git fast-import <input &&
git whatchanged branch'
-test_expect_success \
- 'D: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'D: verify pack' '
+ verify_packs
+'
cat >expect <<EOF
:000000 100755 0000000000000000000000000000000000000000 35a59026a33beac1569b1c7f66f3090ce9c09afc A newdir/exec.sh
test_expect_success \
'E: rfc2822 date, --date-format=rfc2822' \
'git fast-import --date-format=rfc2822 <input'
-test_expect_success \
- 'E: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'E: verify pack' '
+ verify_packs
+'
cat >expect <<EOF
author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500
fi
fi
'
-test_expect_success \
- 'F: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'F: verify pack' '
+ verify_packs
+'
cat >expect <<EOF
tree `git rev-parse branch~1^{tree}`
test_expect_success \
'G: non-fast-forward update forced' \
'git fast-import --force <input'
-test_expect_success \
- 'G: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'G: verify pack' '
+ verify_packs
+'
+
test_expect_success \
'G: branch changed, but logged' \
'test $old_branch != `git rev-parse --verify branch^0` &&
'H: deletall, add 1' \
'git fast-import <input &&
git whatchanged H'
-test_expect_success \
- 'H: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'H: verify pack' '
+ verify_packs
+'
cat >expect <<EOF
:100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf
'Q: commit notes' \
'git fast-import <input &&
git whatchanged notes-test'
-test_expect_success \
- 'Q: verify pack' \
- 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
+
+test_expect_success 'Q: verify pack' '
+ verify_packs
+'
commit1=$(git rev-parse notes-test~2)
commit2=$(git rev-parse notes-test^)
'R: blob bigger than threshold' \
'test_create_repo R &&
git --git-dir=R/.git fast-import --big-file-threshold=1 <input'
-test_expect_success \
- 'R: verify created pack' \
- ': >verify &&
- for p in R/.git/objects/pack/*.pack;
- do
- git verify-pack -v $p >>verify || exit;
- done'
+
+test_expect_success 'R: verify created pack' '
+ (
+ cd R &&
+ verify_packs -v > ../verify
+ )
+'
+
test_expect_success \
'R: verify written objects' \
'git --git-dir=R/.git cat-file blob big-file:big1 >actual &&
git checkout -b marks master &&
git fast-export --export-marks=tmp-marks HEAD &&
test -s tmp-marks &&
- test $(wc -l < tmp-marks) -eq 3 &&
+ test_line_count = 3 tmp-marks &&
test $(
git fast-export --import-marks=tmp-marks\
--export-marks=tmp-marks HEAD |
grep ^commit\ |
wc -l) \
-eq 1 &&
- test $(wc -l < tmp-marks) -eq 4
+ test_line_count = 4 tmp-marks
'
cd cvswork &&
GIT_CONFIG="$git_config" cvs update &&
GIT_CONFIG="$git_config" cvs status | grep "^File: status.file" >../out &&
- test $(wc -l <../out) = 2
+ test_line_count = 2 ../out
'
cd "$WORKDIR"
test_expect_success 'cvs status (nonrecursive)' '
cd cvswork &&
GIT_CONFIG="$git_config" cvs status -l | grep "^File: status.file" >../out &&
- test $(wc -l <../out) = 1
+ test_line_count = 1 ../out
'
cd "$WORKDIR"
cd "$WORKDIR"
test_expect_success 'cvs co -c (shows module database)' '
GIT_CONFIG="$git_config" cvs co -c > out &&
- grep "^master[ ]\+master$" < out &&
- ! grep -v "^master[ ]\+master$" < out
+ grep "^master[ ][ ]*master$" <out &&
+ ! grep -v "^master[ ][ ]*master$" <out
'
#------------
;;
esac
+( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1
test -z "$NO_PERL" && test_set_prereq PERL
test -z "$NO_PYTHON" && test_set_prereq PYTHON
test -n "$USE_LIBPCRE" && test_set_prereq LIBPCRE
{
struct ref *ref;
int n = 0;
+ unsigned char head_sha1[20];
+ char *head;
+
+ head = resolve_refdup("HEAD", head_sha1, 1, NULL);
if (verbose) {
for (ref = refs; ref; ref = ref->next)
ref->status != REF_STATUS_UPTODATE &&
ref->status != REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
- if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD)
- *nonfastforward = 1;
+ if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD &&
+ *nonfastforward != NON_FF_HEAD) {
+ if (!strcmp(head, ref->name))
+ *nonfastforward = NON_FF_HEAD;
+ else
+ *nonfastforward = NON_FF_OTHER;
+ }
}
}
void transport_set_verbosity(struct transport *transport, int verbosity,
int force_progress);
+#define NON_FF_HEAD 1
+#define NON_FF_OTHER 2
int transport_push(struct transport *connection,
int refspec_nr, const char **refspec, int flags,
int * nonfastforward);
opts->unpack_rejects[i].strdup_strings = 1;
}
-static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
- unsigned int set, unsigned int clear)
+static void do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
+ unsigned int set, unsigned int clear)
{
- unsigned int size = ce_size(ce);
- struct cache_entry *new = xmalloc(size);
-
clear |= CE_HASHED | CE_UNHASHED;
if (set & CE_REMOVE)
set |= CE_WT_REMOVE;
+ ce->next = NULL;
+ ce->ce_flags = (ce->ce_flags & ~clear) | set;
+ add_index_entry(&o->result, ce,
+ ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
+}
+
+static void add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
+ unsigned int set, unsigned int clear)
+{
+ unsigned int size = ce_size(ce);
+ struct cache_entry *new = xmalloc(size);
+
memcpy(new, ce, size);
- new->next = NULL;
- new->ce_flags = (new->ce_flags & ~clear) | set;
- add_index_entry(&o->result, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
+ do_add_entry(o, new, set, clear);
}
/*
for (i = 0; i < n; i++)
if (src[i] && src[i] != o->df_conflict_entry)
- add_entry(o, src[i], 0, 0);
+ do_add_entry(o, src[i], 0, 0);
return 0;
}
if (unpack_nondirectories(n, mask, dirmask, src, names, info) < 0)
return -1;
- if (src[0]) {
+ if (o->merge && src[0]) {
if (ce_stage(src[0]))
mark_ce_used_same_name(src[0], o);
else
#define XDF_IGNORE_WHITESPACE (1 << 2)
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3)
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4)
-#define XDF_PATIENCE_DIFF (1 << 5)
-#define XDF_HISTOGRAM_DIFF (1 << 6)
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL)
-#define XDL_PATCH_NORMAL '-'
-#define XDL_PATCH_REVERSE '+'
-#define XDL_PATCH_MODEMASK ((1 << 8) - 1)
-#define XDL_PATCH_IGNOREBSPACE (1 << 8)
+#define XDF_PATIENCE_DIFF (1 << 5)
+#define XDF_HISTOGRAM_DIFF (1 << 6)
+#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
+#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
#define XDL_EMIT_FUNCNAMES (1 << 0)
#define XDL_EMIT_COMMON (1 << 1)
xdalgoenv_t xenv;
diffdata_t dd1, dd2;
- if (xpp->flags & XDF_PATIENCE_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
return xdl_do_patience_diff(mf1, mf2, xpp, xe);
- if (xpp->flags & XDF_HISTOGRAM_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
int line1, int count1, int line2, int count2)
{
xpparam_t xpp;
- xpp.flags = index->xpp->flags & ~XDF_HISTOGRAM_DIFF;
+ xpp.flags = index->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(index->env, &xpp,
line1, count1, line2, count2);
int line1, int count1, int line2, int count2)
{
xpparam_t xpp;
- xpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;
+ xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
return xdl_fall_back_diff(map->env, &xpp,
line1, count1, line2, count2);
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
goto abort;
- if (xpp->flags & XDF_HISTOGRAM_DIFF)
+ if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
hbits = hsize = 0;
else {
hbits = xdl_hashbits((unsigned int) narec);
crec->ha = hav;
recs[nrec++] = crec;
- if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
goto abort;
}
}
* (nrecs) will be updated correctly anyway by
* xdl_prepare_ctx().
*/
- sample = xpp->flags & XDF_HISTOGRAM_DIFF ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1;
+ sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
+ ? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
enl1 = xdl_guess_lines(mf1, sample) + 1;
enl2 = xdl_guess_lines(mf2, sample) + 1;
- if (!(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) {
-
+ if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
+ xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
return -1;
- }
if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
return -1;
}
- if (!(xpp->flags & XDF_PATIENCE_DIFF) &&
- !(xpp->flags & XDF_HISTOGRAM_DIFF) &&
- xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
+ if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
+ (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
+ xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
xdl_free_ctx(&xe->xdf2);
xdl_free_ctx(&xe->xdf1);