Git 2.23-rc0

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE4fA2sf7nIh/HeOzvsLXohpav5ssFAl0/TmEACgkQsLXohpav
 5stWchAA7sWt6Qd5zqtMAT96bEtPIvSVSIzYqg8m2UQL8alDIkXrWUiZGqD7hA9Q
 hkIoDXB1fH8Q7OlJxfAplnnrkea/ARStkBBHo4KB92QUObf2LvHD4thv4iYiTof9
 CchgVnIKH+Jr6ZAgtZw9knV+w86CO7NOrwAWBVf9s81GNWkARuPlsYWs7GDCds2j
 51DPgVNUNr1PNlzKxnScaCKnuwon5kFhMxJo4pQSjJO0ezqV/5MjcOzJBCsTItgc
 EDQUzvVKj8NF8P0eF4AfLjdWr57PMqSImHAvYpt7lDSG0g72xAQ55PGR7fT8fmZr
 yHZFs0H7Bh2TC55DYg92SCm8FKZEN6YNqiXEGwxIPanaNtMwz+huUjaSISGQG5rP
 qh4NFXBU6QoyhxJE5M2SLdOWdpBeTXOfUwDB0SS4NPaEHDBjj5alzdJVm2fJYyXh
 Rg+B2IpzcL3R9Le6EORPhUb8J27XkoxVihZBN8tS5nD0Y6A/e6qacVBOT7aW2lij
 /HSTMOkY/DM6BnEdnPYRoAQTEQJXCEkYYl9Lkqe8XFGCRDw5lbJSDWu0oXmOoAux
 BmaMZW4M+35RswaOGOngC1kbtmDoU00gDo91b6V5y/PJOZvXZJsKGyx7aUbWIlzR
 HNUoLtb9/ZeyzgBslp96lILY8chbUTPQ/t1BjiS2EFFE/izdCAE=
 =kdAI
 -----END PGP SIGNATURE-----

Merge tag 'v2.23.0-rc0' of git://git.kernel.org/pub/scm/git/git

Git 2.23-rc0

* tag 'v2.23.0-rc0' of git://git.kernel.org/pub/scm/git/git: (420 commits)
  Git 2.23-rc0
  Merge fixes made on the 'master' front
  Flush fixes up to the third batch post 2.22.0
  The seventh batch
  git: mark cmd_rebase as requiring a worktree
  rebase: fix white-space
  xdiff: clamp function context indices in post-image
  grep: print the pcre2_jit_on value
  t6200: use test_commit_bulk
  travis-ci: build with GCC 4.8 as well
  The sixth batch
  clean: show an error message when the path is too long
  CodingGuidelines: spell out post-C89 rules
  README: fix rendering of text in angle brackets
  rm: resolving by removal is not a warning-worthy event
  transport-helper: avoid var decl in for () loop control
  stash: fix handling removed files with --keep-index
  mingw: support spawning programs containing spaces in their names
  gpg-interface: do not scan past the end of buffer
  tests: defang pager tests by explicitly disabling the log.mailmap warning
  ...
This commit is contained in:
Jiang Xin 2019-07-30 09:56:16 +08:00
commit eccd872c76
400 changed files with 14848 additions and 3732 deletions

View File

@ -148,8 +148,21 @@ SpacesInSquareBrackets: false
Cpp11BracedListStyle: false Cpp11BracedListStyle: false
# A list of macros that should be interpreted as foreach loops instead of as # A list of macros that should be interpreted as foreach loops instead of as
# function calls. # function calls. Taken from:
ForEachMacros: ['for_each_string_list_item', 'for_each_wanted_builtin', 'for_each_builtin', 'for_each_ut'] # git grep -h '^#define [^[:space:]]*for_each[^[:space:]]*(' \
# | sed "s,^#define \([^[:space:]]*for_each[^[:space:]]*\)(.*$, - '\1'," \
# | sort | uniq
ForEachMacros:
- 'for_each_abbrev'
- 'for_each_builtin'
- 'for_each_string_list_item'
- 'for_each_ut'
- 'for_each_wanted_builtin'
- 'list_for_each'
- 'list_for_each_dir'
- 'list_for_each_prev'
- 'list_for_each_prev_safe'
- 'list_for_each_safe'
# The maximum number of consecutive empty lines to keep. # The maximum number of consecutive empty lines to keep.
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1

1
.gitattributes vendored
View File

@ -5,6 +5,7 @@
*.pl eof=lf diff=perl *.pl eof=lf diff=perl
*.pm eol=lf diff=perl *.pm eol=lf diff=perl
*.py eol=lf diff=python *.py eol=lf diff=python
*.bat eol=crlf
/Documentation/**/*.txt eol=lf /Documentation/**/*.txt eol=lf
/command-list.txt eol=lf /command-list.txt eol=lf
/GIT-VERSION-GEN eol=lf /GIT-VERSION-GEN eol=lf

11
.gitignore vendored
View File

@ -58,6 +58,7 @@
/git-difftool /git-difftool
/git-difftool--helper /git-difftool--helper
/git-describe /git-describe
/git-env--helper
/git-fast-export /git-fast-export
/git-fast-import /git-fast-import
/git-fetch /git-fetch
@ -122,9 +123,6 @@
/git-range-diff /git-range-diff
/git-read-tree /git-read-tree
/git-rebase /git-rebase
/git-rebase--am
/git-rebase--common
/git-rebase--interactive
/git-rebase--preserve-merges /git-rebase--preserve-merges
/git-receive-pack /git-receive-pack
/git-reflog /git-reflog
@ -142,6 +140,7 @@
/git-request-pull /git-request-pull
/git-rerere /git-rerere
/git-reset /git-reset
/git-restore
/git-rev-list /git-rev-list
/git-rev-parse /git-rev-parse
/git-revert /git-revert
@ -166,6 +165,7 @@
/git-submodule /git-submodule
/git-submodule--helper /git-submodule--helper
/git-svn /git-svn
/git-switch
/git-symbolic-ref /git-symbolic-ref
/git-tag /git-tag
/git-unpack-file /git-unpack-file
@ -226,6 +226,11 @@
*.user *.user
*.idb *.idb
*.pdb *.pdb
*.ilk
*.iobj
*.ipdb
*.dll
.vs/
/Debug/ /Debug/
/Release/ /Release/
*.dSYM *.dSYM

View File

@ -21,6 +21,10 @@ matrix:
compiler: compiler:
addons: addons:
before_install: before_install:
- env: jobname=linux-gcc-4.8
os: linux
dist: trusty
compiler:
- env: jobname=Linux32 - env: jobname=Linux32
os: linux os: linux
compiler: compiler:

View File

@ -195,10 +195,30 @@ For C programs:
by e.g. "echo DEVELOPER=1 >>config.mak". by e.g. "echo DEVELOPER=1 >>config.mak".
- We try to support a wide range of C compilers to compile Git with, - We try to support a wide range of C compilers to compile Git with,
including old ones. That means that you should not use C99 including old ones. You should not use features from newer C
initializers, even if a lot of compilers grok it. standard, even if your compiler groks them.
- Variables have to be declared at the beginning of the block. There are a few exceptions to this guideline:
. since early 2012 with e1327023ea, we have been using an enum
definition whose last element is followed by a comma. This, like
an array initializer that ends with a trailing comma, can be used
to reduce the patch noise when adding a new identifer at the end.
. since mid 2017 with cbc0f81d, we have been using designated
initializers for struct (e.g. "struct t v = { .val = 'a' };").
. since mid 2017 with 512f41cf, we have been using designated
initializers for array (e.g. "int array[10] = { [5] = 2 }").
These used to be forbidden, but we have not heard any breakage
report, and they are assumed to be safe.
- Variables have to be declared at the beginning of the block, before
the first statement (i.e. -Wdeclaration-after-statement).
- Declaring a variable in the for loop "for (int i = 0; i < 10; i++)"
is still not allowed in this codebase.
- NULL pointers shall be written as NULL, not as 0. - NULL pointers shall be written as NULL, not as 0.
@ -412,6 +432,12 @@ For C programs:
must be declared with "extern" in header files. However, function must be declared with "extern" in header files. However, function
declarations should not use "extern", as that is already the default. declarations should not use "extern", as that is already the default.
- You can launch gdb around your program using the shorthand GIT_DEBUGGER.
Run `GIT_DEBUGGER=1 ./bin-wrappers/git foo` to simply use gdb as is, or
run `GIT_DEBUGGER="<debugger> <debugger-args>" ./bin-wrappers/git foo` to
use your own debugger and arguments. Example: `GIT_DEBUGGER="ddd --gdb"
./bin-wrappers/git log` (See `wrap-for-bin.sh`.)
For Perl programs: For Perl programs:
- Most of the C guidelines above apply. - Most of the C guidelines above apply.

View File

@ -76,6 +76,7 @@ SP_ARTICLES += howto/maintain-git
API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
SP_ARTICLES += $(API_DOCS) SP_ARTICLES += $(API_DOCS)
TECH_DOCS += MyFirstContribution
TECH_DOCS += SubmittingPatches TECH_DOCS += SubmittingPatches
TECH_DOCS += technical/hash-function-transition TECH_DOCS += technical/hash-function-transition
TECH_DOCS += technical/http-protocol TECH_DOCS += technical/http-protocol

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
Git 2.22.1 Release Notes
========================
Fixes since v2.22
-----------------
* A relative pathname given to "git init --template=<path> <repo>"
ought to be relative to the directory "git init" gets invoked in,
but it instead was made relative to the repository, which has been
corrected.
* "git worktree add" used to fail when another worktree connected to
the same repository was corrupt, which has been corrected.
* The ownership rule for the file descriptor to fast-import remote
backend was mixed up, leading to unrelated file descriptor getting
closed, which has been fixed.
* "git update-server-info" used to leave stale packfiles in its
output, which has been corrected.
* The server side support for "git fetch" used to show incorrect
value for the HEAD symbolic ref when the namespace feature is in
use, which has been corrected.
* "git am -i --resolved" segfaulted after trying to see a commit as
if it were a tree, which has been corrected.
* "git bundle verify" needs to see if prerequisite objects exist in
the receiving repository, but the command did not check if we are
in a repository upfront, which has been corrected.
* "git merge --squash" is designed to update the working tree and the
index without creating the commit, and this cannot be countermanded
by adding the "--commit" option; the command now refuses to work
when both options are given.
* The data collected by fsmonitor was not properly written back to
the on-disk index file, breaking t7519 tests occasionally, which
has been corrected.
* Update to Unicode 12.1 width table.
* The command line to invoke a "git cat-file" command from inside
"git p4" was not properly quoted to protect a caret and running a
broken command on Windows, which has been corrected.
* "git request-pull" learned to warn when the ref we ask them to pull
from in the local repository and in the published repository are
different.
* When creating a partial clone, the object filtering criteria is
recorded for the origin of the clone, but this incorrectly used a
hardcoded name "origin" to name that remote; it has been corrected
to honor the "--origin <name>" option.
* "git fetch" into a lazy clone forgot to fetch base objects that are
necessary to complete delta in a thin packfile, which has been
corrected.
* The filter_data used in the list-objects-filter (which manages a
lazily sparse clone repository) did not use the dynamic array API
correctly---'nr' is supposed to point at one past the last element
of the array in use. This has been corrected.
* The description about slashes in gitignore patterns (used to
indicate things like "anchored to this level only" and "only
matches directories") has been revamped.
* The URL decoding code has been updated to avoid going past the end
of the string while parsing %-<hex>-<hex> sequence.
* The list of for-each like macros used by clang-format has been
updated.
* "git push --atomic" that goes over the transport-helper (namely,
the smart http transport) failed to prevent refs to be pushed when
it can locally tell that one of the ref update will fail without
having to consult the other end, which has been corrected.
* "git clean" silently skipped a path when it cannot lstat() it; now
it gives a warning.
* A codepath that reads from GPG for signed object verification read
past the end of allocated buffer, which has been fixed.
* "git rm" to resolve a conflicted path leaked an internal message
"needs merge" before actually removing the path, which was
confusing. This has been corrected.
* The "git clone" documentation refers to command line options in its
description in the short form; they have been replaced with long
forms to make them more recognisable.
* The configuration variable rebase.rescheduleFailedExec should be
effective only while running an interactive rebase and should not
affect anything when running an non-interactive one, which was not
the case. This has been corrected.
* "git submodule foreach" did not protect command line options passed
to the command to be run in each submodule correctly, when the
"--recursive" option was in use.
* Use "Erase in Line" CSI sequence that is already used in the editor
support to clear cruft in the progress output.
* The codepath to compute delta islands used to spew progress output
without giving the callers any way to squelch it, which has been
fixed.
* The code to parse scaled numbers out of configuration files has
been made more robust and also easier to follow.
* An incorrect list of options was cached after command line
completion failed (e.g. trying to complete a command that requires
a repository outside one), which has been corrected.
* "git rebase --abort" used to leave refs/rewritten/ when concluding
"git rebase -r", which has been corrected.
* "git stash show 23" used to work, but no more after getting
rewritten in C; this regression has been corrected.
* "git interpret-trailers" always treated '#' as the comment
character, regardless of core.commentChar setting, which has been
corrected.
* Code clean-up to avoid signed integer overlaps during binary search.
* "git checkout -p" needs to selectively apply a patch in reverse,
which did not work well.
* The commit-graph file is now part of the "files that the runtime
may keep open file descriptors on, all of which would need to be
closed when done with the object store", and the file descriptor to
an existing commit-graph file now is closed before "gc" finalizes a
new instance to replace it.
* Code restructuring during 2.20 period broke fetching tags via
"import" based transports.
* We have been trying out a few language features outside c89; the
coding guidelines document did not talk about them and instead had
a blanket ban against them.
Also contains various documentation updates, code clean-ups and minor fixups.

View File

@ -0,0 +1,410 @@
Git 2.23 Release Notes
======================
Updates since v2.22
-------------------
Backward compatibility note
* The "--base" option of "format-patch" computed the patch-ids for
prerequisite patches in an unstable way, which has been updated to
compute in a way that is compatible with "git patch-id --stable".
UI, Workflows & Features
* The "git fast-export/import" pair has been taught to handle commits
with log messages in encoding other than UTF-8 better.
* In recent versions of Git, per-worktree refs are exposed in
refs/worktrees/<wtname>/ hierarchy, which means that worktree names
must be a valid refname component. The code now sanitizes the names
given to worktrees, to make sure these refs are well-formed.
* "git merge" learned "--quit" option that cleans up the in-progress
merge while leaving the working tree and the index still in a mess.
* "git format-patch" learns a configuration to set the default for
its --notes=<ref> option.
* The code to show args with potential typo that cannot be
interpreted as a commit-ish has been improved.
* "git clone --recurse-submodules" learned to set up the submodules
to ignore commit object names recorded in the superproject gitlink
and instead use the commits that happen to be at the tip of the
remote-tracking branches from the get-go, by passing the new
"--remote-submodules" option.
* The pattern "git diff/grep" use to extract funcname and words
boundary for Matlab has been extend to cover Octave, which is more
or less equivalent.
* "git help git" was hard to discover (well, at least for some
people).
* The pattern "git diff/grep" use to extract funcname and words
boundary for Rust has been added.
* "git status" can be told a non-standard default value for the
"--[no-]ahead-behind" option with a new configuration variable
status.aheadBehind.
* "git fetch" and "git pull" reports when a fetch results in
non-fast-forward updates to let the user notice unusual situation.
The commands learned "--no-shown-forced-updates" option to disable
this safety feature.
* Two new commands "git switch" and "git restore" are introduced to
split "checking out a branch to work on advancing its history" and
"checking out paths out of the index and/or a tree-ish to work on
advancing the current history" out of the single "git checkout"
command.
* "git branch --list" learned to always output the detached HEAD as
the first item (when the HEAD is detached, of course), regardless
of the locale.
* The conditional inclusion mechanism learned to base the choice on
the branch the HEAD currently is on.
* "git rev-list --objects" learned with "--no-object-names" option to
squelch the path to the object that is used as a grouping hint for
pack-objects.
* A new tag.gpgSign configuration variable turns "git tag -a" into
"git tag -s".
* "git multi-pack-index" learned expire and repack subcommands.
* "git blame" learned to "ignore" commits in the history, whose
effects (as well as their presence) get ignored.
* "git cherry-pick/revert" learned a new "--skip" action.
* The tips of refs from the alternate object store can be used as
starting point for reachability computation now.
* Extra blank lines in "git status" output have been reduced.
* The commits in a repository can be described by multiple
commit-graph files now, which allows the commit-graph files to be
updated incrementally.
* The "git log" command learns to issue a warning when log.mailmap
configuration is not set and --[no-]mailmap option is not used, to
prepare users for future versions of Git that uses the mailmap by
default.
* "git range-diff" output has been tweaked for easier identification
of which part of what file the patch shown is about.
Performance, Internal Implementation, Development Support etc.
* Update supporting parts of "git rebase" to remove code that should
no longer be used.
* Developer support to emulate unsatisfied prerequisites in tests to
ensure that the remainer of the tests still succeeds when tests
with prerequisites are skipped.
* "git update-server-info" learned not to rewrite the file with the
same contents.
* The way of specifying the path to find dynamic libraries at runtime
has been simplified. The old default to pass -R/path/to/dir has been
replaced with the new default to pass -Wl,-rpath,/path/to/dir,
which is the more recent GCC uses. Those who need to build with an
old GCC can still use "CC_LD_DYNPATH=-R"
* Prepare use of reachability index in topological walker that works
on a range (A..B).
* A new tutorial targetting specifically aspiring git-core
developers has been added.
* Auto-detect how to tell HP-UX aCC where to use dynamically linked
libraries from at runtime.
* "git mergetool" and its tests now spawn fewer subprocesses.
* Dev support update to help tracing out tests.
* Support to build with MSVC has been updated.
* "git fetch" that grabs from a group of remotes learned to run the
auto-gc only once at the very end.
* A handful of Windows build patches have been upstreamed.
* The code to read state files used by the sequencer machinery for
"git status" has been made more robust against a corrupt or stale
state files.
* "git for-each-ref" with multiple patterns have been optimized.
* The tree-walk API learned to pass an in-core repository
instance throughout more codepaths.
* When one step in multi step cherry-pick or revert is reset or
committed, the command line prompt script failed to notice the
current status, which has been improved.
* Many GIT_TEST_* environment variables control various aspects of
how our tests are run, but a few followed "non-empty is true, empty
or unset is false" while others followed the usual "there are a few
ways to spell true, like yes, on, etc., and also ways to spell
false, like no, off, etc." convention.
* Adjust the dir-iterator API and apply it to the local clone
optimization codepath.
* We have been trying out a few language features outside c89; the
coding guidelines document did not talk about them and instead had
a blanket ban against them.
(merge cc0c42975a jc/post-c89-rules-doc later to maint).
* A test helper has been introduced to optimize preparation of test
repositories with many simple commits, and a handful of test
scripts have been updated to use it.
Fixes since v2.22
-----------------
* A relative pathname given to "git init --template=<path> <repo>"
ought to be relative to the directory "git init" gets invoked in,
but it instead was made relative to the repository, which has been
corrected.
(merge e1df7fe43f nd/init-relative-template-fix later to maint).
* "git worktree add" used to fail when another worktree connected to
the same repository was corrupt, which has been corrected.
(merge 105df73e71 nd/corrupt-worktrees later to maint).
* The ownership rule for the file descriptor to fast-import remote
backend was mixed up, leading to unrelated file descriptor getting
closed, which has been fixed.
(merge 3203566a71 mh/import-transport-fd-fix later to maint).
* A "merge -c" instruction during "git rebase --rebase-merges" should
give the user a chance to edit the log message, even when there is
otherwise no need to create a new merge and replace the existing
one (i.e. fast-forward instead), but did not. Which has been
corrected.
* Code cleanup and futureproof.
(merge 31f5256c82 ds/object-info-for-prefetch-fix later to maint).
* More parameter validation.
(merge de99eb0c24 es/grep-require-name-when-needed later to maint).
* "git update-server-info" used to leave stale packfiles in its
output, which has been corrected.
(merge e941c48d49 ew/server-info-remove-crufts later to maint).
* The server side support for "git fetch" used to show incorrect
value for the HEAD symbolic ref when the namespace feature is in
use, which has been corrected.
(merge 533e088250 jk/HEAD-symref-in-xfer-namespaces later to maint).
* "git am -i --resolved" segfaulted after trying to see a commit as
if it were a tree, which has been corrected.
(merge 7663e438c5 jk/am-i-resolved-fix later to maint).
* "git bundle verify" needs to see if prerequisite objects exist in
the receiving repository, but the command did not check if we are
in a repository upfront, which has been corrected.
(merge 3bbbe467f2 js/bundle-verify-require-object-store later to maint).
* "git merge --squash" is designed to update the working tree and the
index without creating the commit, and this cannot be countermanded
by adding the "--commit" option; the command now refuses to work
when both options are given.
(merge 1d14d0c994 vv/merge-squash-with-explicit-commit later to maint).
* The data collected by fsmonitor was not properly written back to
the on-disk index file, breaking t7519 tests occasionally, which
has been corrected.
(merge b5a8169752 js/fsmonitor-unflake later to maint).
* Update to Unicode 12.1 width table.
(merge 5817f9caa3 bb/unicode-12.1-reiwa later to maint).
* The command line to invoke a "git cat-file" command from inside
"git p4" was not properly quoted to protect a caret and running a
broken command on Windows, which has been corrected.
(merge c3f2358de3 mm/p4-unshelve-windows-fix later to maint).
* "git request-pull" learned to warn when the ref we ask them to pull
from in the local repository and in the published repository are
different.
(merge 0454220d66 pb/request-pull-verify-remote-ref later to maint).
* When creating a partial clone, the object filtering criteria is
recorded for the origin of the clone, but this incorrectly used a
hardcoded name "origin" to name that remote; it has been corrected
to honor the "--origin <name>" option.
(merge 1c4a9f9114 xl/record-partial-clone-origin later to maint).
* "git fetch" into a lazy clone forgot to fetch base objects that are
necessary to complete delta in a thin packfile, which has been
corrected.
(merge 810e19322d jt/partial-clone-missing-ref-delta-base later to maint).
* The filter_data used in the list-objects-filter (which manages a
lazily sparse clone repository) did not use the dynamic array API
correctly---'nr' is supposed to point at one past the last element
of the array in use. This has been corrected.
(merge 7140600e2e md/list-objects-filter-memfix later to maint).
* The description about slashes in gitignore patterns (used to
indicate things like "anchored to this level only" and "only
matches directories") has been revamped.
(merge 1a58bad014 an/ignore-doc-update later to maint).
* The URL decoding code has been updated to avoid going past the end
of the string while parsing %-<hex>-<hex> sequence.
(merge d37dc239a4 md/url-parse-harden later to maint).
* The list of for-each like macros used by clang-format has been
updated.
(merge fc7e03aace mo/clang-format-for-each-update later to maint).
* "git branch --list" learned to show branches that are checked out
in other worktrees connected to the same repository prefixed with
'+', similar to the way the currently checked out branch is shown
with '*' in front.
(merge 6e9381469e nb/branch-show-other-worktrees-head later to maint).
* Code restructuring during 2.20 period broke fetching tags via
"import" based transports.
(merge f80d922355 fc/fetch-with-import-fix later to maint).
* The commit-graph file is now part of the "files that the runtime
may keep open file descriptors on, all of which would need to be
closed when done with the object store", and the file descriptor to
an existing commit-graph file now is closed before "gc" finalizes a
new instance to replace it.
(merge 2d511cfc0b ds/close-object-store later to maint).
* "git checkout -p" needs to selectively apply a patch in reverse,
which did not work well.
(merge 2bd69b9024 pw/add-p-recount later to maint).
* Code clean-up to avoid signed integer wraparounds during binary search.
(merge 568a05c5ec rs/avoid-overflow-in-midpoint-computation later to maint).
* "git interpret-trailers" always treated '#' as the comment
character, regardless of core.commentChar setting, which has been
corrected.
(merge 29c83fc23f jk/trailers-use-config later to maint).
* "git stash show 23" used to work, but no more after getting
rewritten in C; this regression has been corrected.
(merge 63b50c8ffe tg/stash-ref-by-index-fix later to maint).
* "git rebase --abort" used to leave refs/rewritten/ when concluding
"git rebase -r", which has been corrected.
(merge d559f502c5 pw/rebase-abort-clean-rewritten later to maint).
* An incorrect list of options was cached after command line
completion failed (e.g. trying to complete a command that requires
a repository outside one), which has been corrected.
(merge 69702523af nd/completion-no-cache-failure later to maint).
* The code to parse scaled numbers out of configuration files has
been made more robust and also easier to follow.
(merge 39c575c969 rs/config-unit-parsing later to maint).
* The codepath to compute delta islands used to spew progress output
without giving the callers any way to squelch it, which has been
fixed.
(merge bdbdf42f8a jk/delta-islands-progress-fix later to maint).
* Protocol capabilities that go over wire should never be translated,
but it was incorrectly marked for translation, which has been
corrected. The output of protocol capabilities for debugging has
been tweaked a bit.
* Use "Erase in Line" CSI sequence that is already used in the editor
support to clear cruft in the progress output.
(merge 5b12e3123b sg/rebase-progress later to maint).
* "git submodule foreach" did not protect command line options passed
to the command to be run in each submodule correctly, when the
"--recursive" option was in use.
(merge 30db18b148 ms/submodule-foreach-fix later to maint).
* The configuration variable rebase.rescheduleFailedExec should be
effective only while running an interactive rebase and should not
affect anything when running an non-interactive one, which was not
the case. This has been corrected.
(merge 906b63942a js/rebase-reschedule-applies-only-to-interactive later to maint).
* The "git clone" documentation refers to command line options in its
description in the short form; they have been replaced with long
forms to make them more recognisable.
(merge bfc8c84ed5 qn/clone-doc-use-long-form later to maint).
* Generation of pack bitmaps are now disabled when .keep files exist,
as these are mutually exclusive features.
(merge 7328482253 ew/repack-with-bitmaps-by-default later to maint).
* "git rm" to resolve a conflicted path leaked an internal message
"needs merge" before actually removing the path, which was
confusing. This has been corrected.
(merge b2b1f615ce jc/denoise-rm-to-resolve later to maint).
* "git stash --keep-index" did not work correctly on paths that have
been removed, which has been fixed.
(merge b932f6a5e8 tg/stash-keep-index-with-removed-paths later to maint).
* Window 7 update ;-)
(merge eb7c786314 js/mingw-spawn-with-spaces-in-path later to maint).
* A codepath that reads from GPG for signed object verification read
past the end of allocated buffer, which has been fixed.
(merge 64c45dc72e sr/gpg-interface-stop-at-the-end later to maint).
* "git clean" silently skipped a path when it cannot lstat() it; now
it gives a warning.
(merge b09364c47a js/clean-report-too-long-a-path later to maint).
* "git push --atomic" that goes over the transport-helper (namely,
the smart http transport) failed to prevent refs to be pushed when
it can locally tell that one of the ref update will fail without
having to consult the other end, which has been corrected.
(merge 2581ea3d31 es/local-atomic-push-failure-with-http later to maint).
* The internal diff machinery can be made to read out of bounds while
looking for --funcion-context line in a corner case, which has been
corrected.
(merge b777f3fd61 jk/xdiff-clamp-funcname-context-index later to maint).
* Other code cleanup, docfix, build fix, etc.
(merge f547101b26 es/git-debugger-doc later to maint).
(merge 7877ac3d7b js/bisect-helper-check-get-oid-return-value later to maint).
(merge 0108f47eb3 sw/git-p4-unshelve-branched-files later to maint).
(merge 9df8f734fd cm/send-email-document-req-modules later to maint).
(merge afc3bf6eb1 ab/hash-object-doc later to maint).
(merge 1fde99cfc7 po/doc-branch later to maint).
(merge 459842e1c2 dl/config-alias-doc later to maint).
(merge 5d137fc2c7 cb/fsmonitor-intfix later to maint).
(merge 921d49be86 rs/copy-array later to maint).
(merge cc8d872e69 js/t3404-typofix later to maint).
(merge 729a9b558b cb/mkstemps-uint-type-fix later to maint).
(merge 9dae4fe79f js/gcc-8-and-9 later to maint).
(merge ed33bd8f30 js/t0001-case-insensitive later to maint).
(merge dfa880e336 jw/gitweb-sample-update later to maint).
(merge e532a90a9f sg/t5551-fetch-smart-error-is-translated later to maint).
(merge 8d45ad8c29 jt/t5551-test-chunked later to maint).
(merge 1a64e07d23 sg/git-C-empty-doc later to maint).
(merge 37a2e35395 sg/ci-brew-gcc-workaround later to maint).
(merge 24df0d49c4 js/trace2-signo-typofix later to maint).
(merge fbec05c210 cc/test-oidmap later to maint).
(merge 7926cee904 di/readme-markup-fix later to maint).
(merge 02638d1e11 vn/xmmap-gently later to maint).
(merge f7bf24d4dd rm/gpg-program-doc-fix later to maint).
(merge 3aef54e8b8 js/unmap-before-ext-diff later to maint).

View File

@ -110,5 +110,24 @@ commit. And the default value is 40. If there are more than one
`-C` options given, the <num> argument of the last `-C` will `-C` options given, the <num> argument of the last `-C` will
take effect. take effect.
--ignore-rev <rev>::
Ignore changes made by the revision when assigning blame, as if the
change never happened. Lines that were changed or added by an ignored
commit will be blamed on the previous commit that changed that line or
nearby lines. This option may be specified multiple times to ignore
more than one revision. If the `blame.markIgnoredLines` config option
is set, then lines that were changed by an ignored commit and attributed to
another commit will be marked with a `?` in the blame output. If the
`blame.markUnblamableLines` config option is set, then those lines touched
by an ignored commit that we could not attribute to another revision are
marked with a '*'.
--ignore-revs-file <file>::
Ignore revisions listed in `file`, which must be in the same format as an
`fsck.skipList`. This option may be repeated, and these files will be
processed after any files specified with the `blame.ignoreRevsFile` config
option. An empty file name, `""`, will clear the list of revs from
previously processed files.
-h:: -h::
Show help message. Show help message.

View File

@ -144,6 +144,20 @@ refer to linkgit:gitignore[5] for details. For convenience:
This is the same as `gitdir` except that matching is done This is the same as `gitdir` except that matching is done
case-insensitively (e.g. on case-insensitive file sytems) case-insensitively (e.g. on case-insensitive file sytems)
`onbranch`::
The data that follows the keyword `onbranch:` is taken to be a
pattern with standard globbing wildcards and two additional
ones, `**/` and `/**`, that can match multiple path components.
If we are in a worktree where the name of the branch that is
currently checked out matches the pattern, the include condition
is met.
+
If the pattern ends with `/`, `**` will be automatically added. For
example, the pattern `foo/` becomes `foo/**`. In other words, it matches
all branches that begin with `foo/`. This is useful if your branches are
organized hierarchically and you would like to apply a configuration to
all the branches in that hierarchy.
A few more notes on matching via `gitdir` and `gitdir/i`: A few more notes on matching via `gitdir` and `gitdir/i`:
* Symlinks in `$GIT_DIR` are not resolved before matching. * Symlinks in `$GIT_DIR` are not resolved before matching.
@ -206,6 +220,11 @@ Example
[includeIf "gitdir:/path/to/group/"] [includeIf "gitdir:/path/to/group/"]
path = foo.inc path = foo.inc
; include only if we are in a worktree where foo-branch is
; currently checked out
[includeIf "onbranch:foo-branch"]
path = foo.inc
Values Values
~~~~~~ ~~~~~~

View File

@ -4,6 +4,10 @@ advice.*::
can tell Git that you do not need help by setting these to 'false': can tell Git that you do not need help by setting these to 'false':
+ +
-- --
fetchShowForcedUpdates::
Advice shown when linkgit:git-fetch[1] takes a long time
to calculate forced updates after ref updates, or to warn
that the check is disabled.
pushUpdateRejected:: pushUpdateRejected::
Set this variable to 'false' if you want to disable Set this variable to 'false' if you want to disable
'pushNonFFCurrent', 'pushNonFFCurrent',
@ -37,12 +41,19 @@ advice.*::
we can still suggest that the user push to either we can still suggest that the user push to either
refs/heads/* or refs/tags/* based on the type of the refs/heads/* or refs/tags/* based on the type of the
source object. source object.
statusAheadBehind::
Shown when linkgit:git-status[1] computes the ahead/behind
counts for a local ref compared to its remote tracking ref,
and that calculation takes longer than expected. Will not
appear if `status.aheadBehind` is false or the option
`--no-ahead-behind` is given.
statusHints:: statusHints::
Show directions on how to proceed from the current Show directions on how to proceed from the current
state in the output of linkgit:git-status[1], in state in the output of linkgit:git-status[1], in
the template shown when writing commit messages in the template shown when writing commit messages in
linkgit:git-commit[1], and in the help message shown linkgit:git-commit[1], and in the help message shown
by linkgit:git-checkout[1] when switching branch. by linkgit:git-switch[1] or
linkgit:git-checkout[1] when switching branch.
statusUoption:: statusUoption::
Advise to consider using the `-u` option to linkgit:git-status[1] Advise to consider using the `-u` option to linkgit:git-status[1]
when the command takes more than 2 seconds to enumerate untracked when the command takes more than 2 seconds to enumerate untracked
@ -57,17 +68,21 @@ advice.*::
resolveConflict:: resolveConflict::
Advice shown by various commands when conflicts Advice shown by various commands when conflicts
prevent the operation from being performed. prevent the operation from being performed.
sequencerInUse::
Advice shown when a sequencer command is already in progress.
implicitIdentity:: implicitIdentity::
Advice on how to set your identity configuration when Advice on how to set your identity configuration when
your information is guessed from the system username and your information is guessed from the system username and
domain name. domain name.
detachedHead:: detachedHead::
Advice shown when you used linkgit:git-checkout[1] to Advice shown when you used
move to the detach HEAD state, to instruct how to create linkgit:git-switch[1] or linkgit:git-checkout[1]
a local branch after the fact. to move to the detach HEAD state, to instruct how to
create a local branch after the fact.
checkoutAmbiguousRemoteBranchName:: checkoutAmbiguousRemoteBranchName::
Advice shown when the argument to Advice shown when the argument to
linkgit:git-checkout[1] ambiguously resolves to a linkgit:git-checkout[1] and linkgit:git-switch[1]
ambiguously resolves to a
remote tracking branch on more than one remote in remote tracking branch on more than one remote in
situations where an unambiguous argument would have situations where an unambiguous argument would have
otherwise caused a remote-tracking branch to be otherwise caused a remote-tracking branch to be

View File

@ -1,18 +1,28 @@
alias.*:: alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g. Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation after defining `alias.last = cat-file commit HEAD`, the invocation
"git last" is equivalent to "git cat-file commit HEAD". To avoid `git last` is equivalent to `git cat-file commit HEAD`. To avoid
confusion and troubles with script usage, aliases that confusion and troubles with script usage, aliases that
hide existing Git commands are ignored. Arguments are split by hide existing Git commands are ignored. Arguments are split by
spaces, the usual shell quoting and escaping is supported. spaces, the usual shell quoting and escaping is supported.
A quote pair or a backslash can be used to quote them. A quote pair or a backslash can be used to quote them.
+ +
Note that the first word of an alias does not necessarily have to be a
command. It can be a command-line option that will be passed into the
invocation of `git`. In particular, this is useful when used with `-c`
to pass in one-time configurations or `-p` to force pagination. For example,
`loud-rebase = -c commit.verbose=true rebase` can be defined such that
running `git loud-rebase` would be equivalent to
`git -c commit.verbose=true rebase`. Also, `ps = -p status` would be a
helpful alias since `git ps` would paginate the output of `git status`
where the original command does not.
+
If the alias expansion is prefixed with an exclamation point, If the alias expansion is prefixed with an exclamation point,
it will be treated as a shell command. For example, defining it will be treated as a shell command. For example, defining
"alias.new = !gitk --all --not ORIG_HEAD", the invocation `alias.new = !gitk --all --not ORIG_HEAD`, the invocation
"git new" is equivalent to running the shell command `git new` is equivalent to running the shell command
"gitk --all --not ORIG_HEAD". Note that shell commands will be `gitk --all --not ORIG_HEAD`. Note that shell commands will be
executed from the top-level directory of a repository, which may executed from the top-level directory of a repository, which may
not necessarily be the current directory. not necessarily be the current directory.
`GIT_PREFIX` is set as returned by running 'git rev-parse --show-prefix' `GIT_PREFIX` is set as returned by running `git rev-parse --show-prefix`
from the original current directory. See linkgit:git-rev-parse[1]. from the original current directory. See linkgit:git-rev-parse[1].

View File

@ -19,3 +19,19 @@ blame.showEmail::
blame.showRoot:: blame.showRoot::
Do not treat root commits as boundaries in linkgit:git-blame[1]. Do not treat root commits as boundaries in linkgit:git-blame[1].
This option defaults to false. This option defaults to false.
blame.ignoreRevsFile::
Ignore revisions listed in the file, one unabbreviated object name per
line, in linkgit:git-blame[1]. Whitespace and comments beginning with
`#` are ignored. This option may be repeated multiple times. Empty
file names will reset the list of ignored revisions. This option will
be handled before the command line option `--ignore-revs-file`.
blame.markUnblamables::
Mark lines that were changed by an ignored revision that we could not
attribute to another commit with a '*' in the output of
linkgit:git-blame[1].
blame.markIgnoredLines::
Mark lines that were changed by an ignored revision that we attributed to
another commit with a '?' in the output of linkgit:git-blame[1].

View File

@ -1,5 +1,5 @@
branch.autoSetupMerge:: branch.autoSetupMerge::
Tells 'git branch' and 'git checkout' to set up new branches Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
so that linkgit:git-pull[1] will appropriately merge from the so that linkgit:git-pull[1] will appropriately merge from the
starting point branch. Note that even if this option is not set, starting point branch. Note that even if this option is not set,
this behavior can be chosen per-branch using the `--track` this behavior can be chosen per-branch using the `--track`
@ -11,7 +11,7 @@ branch.autoSetupMerge::
branch. This option defaults to true. branch. This option defaults to true.
branch.autoSetupRebase:: branch.autoSetupRebase::
When a new branch is created with 'git branch' or 'git checkout' When a new branch is created with 'git branch', 'git switch' or 'git checkout'
that tracks another branch, this variable tells Git to set that tracks another branch, this variable tells Git to set
up pull to rebase instead of merge (see "branch.<name>.rebase"). up pull to rebase instead of merge (see "branch.<name>.rebase").
When `never`, rebase is never automatically set to true. When `never`, rebase is never automatically set to true.

View File

@ -1,5 +1,6 @@
checkout.defaultRemote:: checkout.defaultRemote::
When you run 'git checkout <something>' and only have one When you run 'git checkout <something>'
or 'git switch <something>' and only have one
remote, it may implicitly fall back on checking out and remote, it may implicitly fall back on checking out and
tracking e.g. 'origin/<something>'. This stops working as soon tracking e.g. 'origin/<something>'. This stops working as soon
as you have more than one remote with a '<something>' as you have more than one remote with a '<something>'
@ -8,16 +9,10 @@ checkout.defaultRemote::
disambiguation. The typical use-case is to set this to disambiguation. The typical use-case is to set this to
`origin`. `origin`.
+ +
Currently this is used by linkgit:git-checkout[1] when 'git checkout Currently this is used by linkgit:git-switch[1] and
<something>' will checkout the '<something>' branch on another remote, linkgit:git-checkout[1] when 'git checkout <something>'
or 'git switch <something>'
will checkout the '<something>' branch on another remote,
and by linkgit:git-worktree[1] when 'git worktree add' refers to a and by linkgit:git-worktree[1] when 'git worktree add' refers to a
remote branch. This setting might be used for other checkout-like remote branch. This setting might be used for other checkout-like
commands or functionality in the future. commands or functionality in the future.
checkout.optimizeNewBranch::
Optimizes the performance of "git checkout -b <new_branch>" when
using sparse-checkout. When set to true, git will not update the
repo based on the current sparse-checkout settings. This means it
will not update the skip-worktree bit in the index nor add/remove
files in the working directory to reflect the current sparse checkout
settings nor will it show the local changes.

View File

@ -78,7 +78,8 @@ diff.external::
diff.ignoreSubmodules:: diff.ignoreSubmodules::
Sets the default value of --ignore-submodules. Note that this Sets the default value of --ignore-submodules. Note that this
affects only 'git diff' Porcelain, and not lower level 'diff' affects only 'git diff' Porcelain, and not lower level 'diff'
commands such as 'git diff-files'. 'git checkout' also honors commands such as 'git diff-files'. 'git checkout'
and 'git switch' also honor
this setting when reporting uncommitted changes. Setting it to this setting when reporting uncommitted changes. Setting it to
'all' disables the submodule summary normally shown by 'git commit' 'all' disables the submodule summary normally shown by 'git commit'
and 'git status' when `status.submoduleSummary` is set unless it is and 'git status' when `status.submoduleSummary` is set unless it is

View File

@ -63,3 +63,8 @@ fetch.negotiationAlgorithm::
Unknown values will cause 'git fetch' to error out. Unknown values will cause 'git fetch' to error out.
+ +
See also the `--negotiation-tip` option for linkgit:git-fetch[1]. See also the `--negotiation-tip` option for linkgit:git-fetch[1].
fetch.showForcedUpdates::
Set to false to enable `--no-show-forced-updates` in
linkgit:git-fetch[1] and linkgit:git-pull[1] commands.
Defaults to true.

View File

@ -85,3 +85,18 @@ format.outputDirectory::
format.useAutoBase:: format.useAutoBase::
A boolean value which lets you enable the `--base=auto` option of A boolean value which lets you enable the `--base=auto` option of
format-patch by default. format-patch by default.
format.notes::
Provides the default value for the `--notes` option to
format-patch. Accepts a boolean value, or a ref which specifies
where to get notes. If false, format-patch defaults to
`--no-notes`. If true, format-patch defaults to `--notes`. If
set to a non-boolean value, format-patch defaults to
`--notes=<ref>`, where `ref` is the non-boolean value. Defaults
to false.
+
If one wishes to use the ref `ref/notes/true`, please use that literal
instead.
+
This configuration can be specified multiple times in order to allow
multiple notes refs to be included.

View File

@ -2,7 +2,7 @@ gpg.program::
Use this custom program instead of "`gpg`" found on `$PATH` when Use this custom program instead of "`gpg`" found on `$PATH` when
making or verifying a PGP signature. The program must support the making or verifying a PGP signature. The program must support the
same command-line interface as GPG, namely, to verify a detached same command-line interface as GPG, namely, to verify a detached
signature, "`gpg --verify $file - <$signature`" is run, and the signature, "`gpg --verify $signature - <$file`" is run, and the
program is expected to signal a good signature by exiting with program is expected to signal a good signature by exiting with
code 0, and to generate an ASCII-armored detached signature, the code 0, and to generate an ASCII-armored detached signature, the
standard input of "`gpg -bsau $key`" is fed with the contents to be standard input of "`gpg -bsau $key`" is fed with the contents to be

View File

@ -2,7 +2,8 @@ interactive.singleKey::
In interactive commands, allow the user to provide one-letter In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter). 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-add[1], linkgit:git-checkout[1],
linkgit:git-restore[1], linkgit:git-commit[1],
linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this
setting is silently ignored if portable keystroke input setting is silently ignored if portable keystroke input
is not available; requires the Perl module Term::ReadKey. is not available; requires the Perl module Term::ReadKey.

View File

@ -40,4 +40,5 @@ log.showSignature::
log.mailmap:: log.mailmap::
If true, makes linkgit:git-log[1], linkgit:git-show[1], and If true, makes linkgit:git-log[1], linkgit:git-show[1], and
linkgit:git-whatchanged[1] assume `--use-mailmap`. linkgit:git-whatchanged[1] assume `--use-mailmap`, otherwise
assume `--no-use-mailmap`. False by default.

View File

@ -12,6 +12,11 @@ status.branch::
Set to true to enable --branch by default in linkgit:git-status[1]. Set to true to enable --branch by default in linkgit:git-status[1].
The option --no-branch takes precedence over this variable. The option --no-branch takes precedence over this variable.
status.aheadBehind::
Set to true to enable `--ahead-behind` and false to enable
`--no-ahead-behind` by default in linkgit:git-status[1] for
non-porcelain status formats. Defaults to true.
status.displayCommentPrefix:: status.displayCommentPrefix::
If set to true, linkgit:git-status[1] will insert a comment If set to true, linkgit:git-status[1] will insert a comment
prefix before each output line (starting with prefix before each output line (starting with

View File

@ -8,6 +8,14 @@ tag.sort::
linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the
value of this variable will be used as the default. value of this variable will be used as the default.
tag.gpgSign::
A boolean to specify whether all tags should be GPG signed.
Use of this option when running in an automated script can
result in a large number of tags being signed. It is therefore
convenient to use an agent to avoid typing your gpg passphrase
several times. Note that this option doesn't affects tag signing
behavior enabled by "-u <keyid>" or "--local-user=<keyid>" options.
tar.umask:: tar.umask::
This variable can be used to restrict the permission bits of This variable can be used to restrict the permission bits of
tar archive entries. The default is 0002, which turns off the tar archive entries. The default is 0002, which turns off the

View File

@ -88,6 +88,10 @@ ifndef::git-pull[]
Allow several <repository> and <group> arguments to be Allow several <repository> and <group> arguments to be
specified. No <refspec>s may be specified. specified. No <refspec>s may be specified.
--[no-]auto-gc::
Run `git gc --auto` at the end to perform garbage collection
if needed. This is enabled by default.
-p:: -p::
--prune:: --prune::
Before fetching, remove any remote-tracking references that no Before fetching, remove any remote-tracking references that no
@ -221,6 +225,19 @@ endif::git-pull[]
When multiple `--server-option=<option>` are given, they are all When multiple `--server-option=<option>` are given, they are all
sent to the other side in the order listed on the command line. sent to the other side in the order listed on the command line.
--show-forced-updates::
By default, git checks if a branch is force-updated during
fetch. This can be disabled through fetch.showForcedUpdates, but
the --show-forced-updates option guarantees this check occurs.
See linkgit:git-config[1].
--no-show-forced-updates::
By default, git checks if a branch is force-updated during
fetch. Pass --no-show-forced-updates or set fetch.showForcedUpdates
to false to skip this check for performance reasons. If used during
'git-pull' the --ff-only option will still check for forced updates
before attempting a fast-forward update. See linkgit:git-config[1].
-4:: -4::
--ipv4:: --ipv4::
Use IPv4 addresses only, ignoring IPv6 addresses. Use IPv4 addresses only, ignoring IPv6 addresses.

View File

@ -10,6 +10,7 @@ SYNOPSIS
[verse] [verse]
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
[-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
[--ignore-rev <rev>] [--ignore-revs-file <file>]
[--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>..<rev>] [--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>..<rev>]
[--] <file> [--] <file>

View File

@ -8,12 +8,14 @@ git-branch - List, create, or delete branches
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a] 'git branch' [--color[=<when>] | --no-color] [--show-current]
[--list] [--show-current] [-v [--abbrev=<length> | --no-abbrev]] [-v [--abbrev=<length> | --no-abbrev]]
[--column[=<options>] | --no-column] [--sort=<key>] [--column[=<options>] | --no-column] [--sort=<key>]
[(--merged | --no-merged) [<commit>]] [(--merged | --no-merged) [<commit>]]
[--contains [<commit]] [--no-contains [<commit>]] [--contains [<commit]] [--no-contains [<commit>]]
[--points-at <object>] [--format=<format>] [<pattern>...] [--points-at <object>] [--format=<format>]
[(-r | --remotes) | (-a | --all)]
[--list] [<pattern>...]
'git branch' [--track | --no-track] [-f] <branchname> [<start-point>] 'git branch' [--track | --no-track] [-f] <branchname> [<start-point>]
'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>] 'git branch' (--set-upstream-to=<upstream> | -u <upstream>) [<branchname>]
'git branch' --unset-upstream [<branchname>] 'git branch' --unset-upstream [<branchname>]
@ -26,13 +28,19 @@ DESCRIPTION
----------- -----------
If `--list` is given, or if there are no non-option arguments, existing If `--list` is given, or if there are no non-option arguments, existing
branches are listed; the current branch will be highlighted with an branches are listed; the current branch will be highlighted in green and
asterisk. Option `-r` causes the remote-tracking branches to be listed, marked with an asterisk. Any branches checked out in linked worktrees will
and option `-a` shows both local and remote branches. If a `<pattern>` be highlighted in cyan and marked with a plus sign. Option `-r` causes the
remote-tracking branches to be listed,
and option `-a` shows both local and remote branches.
If a `<pattern>`
is given, it is used as a shell wildcard to restrict the output to is given, it is used as a shell wildcard to restrict the output to
matching branches. If multiple patterns are given, a branch is shown if matching branches. If multiple patterns are given, a branch is shown if
it matches any of the patterns. Note that when providing a it matches any of the patterns.
`<pattern>`, you must use `--list`; otherwise the command is interpreted
Note that when providing a
`<pattern>`, you must use `--list`; otherwise the command may be interpreted
as branch creation. as branch creation.
With `--contains`, shows only the branches that contain the named commit With `--contains`, shows only the branches that contain the named commit
@ -52,7 +60,7 @@ can leave out at most one of `A` and `B`, in which case it defaults to
`HEAD`. `HEAD`.
Note that this will create the new branch, but it will not switch the Note that this will create the new branch, but it will not switch the
working tree to it; use "git checkout <newbranch>" to switch to the working tree to it; use "git switch <newbranch>" to switch to the
new branch. new branch.
When a local branch is started off a remote-tracking branch, Git sets up the When a local branch is started off a remote-tracking branch, Git sets up the
@ -153,10 +161,12 @@ This option is only applicable in non-verbose mode.
-r:: -r::
--remotes:: --remotes::
List or delete (if used with -d) the remote-tracking branches. List or delete (if used with -d) the remote-tracking branches.
Combine with `--list` to match the optional pattern(s).
-a:: -a::
--all:: --all::
List both remote-tracking branches and local branches. List both remote-tracking branches and local branches.
Combine with `--list` to match optional pattern(s).
-l:: -l::
--list:: --list::
@ -174,8 +184,10 @@ This option is only applicable in non-verbose mode.
When in list mode, When in list mode,
show sha1 and commit subject line for each head, along with show sha1 and commit subject line for each head, along with
relationship to upstream branch (if any). If given twice, print relationship to upstream branch (if any). If given twice, print
the name of the upstream branch, as well (see also `git remote the path of the linked worktree (if any) and the name of the upstream
show <remote>`). branch, as well (see also `git remote show <remote>`). Note that the
current worktree's HEAD will not have its path printed (it will always
be your current directory).
-q:: -q::
--quiet:: --quiet::
@ -202,7 +214,7 @@ This option is only applicable in non-verbose mode.
+ +
This behavior is the default when the start point is a remote-tracking branch. This behavior is the default when the start point is a remote-tracking branch.
Set the branch.autoSetupMerge configuration variable to `false` if you Set the branch.autoSetupMerge configuration variable to `false` if you
want `git checkout` and `git branch` to always behave as if `--no-track` want `git switch`, `git checkout` and `git branch` to always behave as if `--no-track`
were given. Set it to `always` if you want this behavior when the were given. Set it to `always` if you want this behavior when the
start-point is either a local or remote-tracking branch. start-point is either a local or remote-tracking branch.
@ -301,7 +313,7 @@ Start development from a known tag::
$ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6 $ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6
$ cd my2.6 $ cd my2.6
$ git branch my2.6.14 v2.6.14 <1> $ git branch my2.6.14 v2.6.14 <1>
$ git checkout my2.6.14 $ git switch my2.6.14
------------ ------------
+ +
<1> This step and the next one could be combined into a single step with <1> This step and the next one could be combined into a single step with
@ -322,13 +334,25 @@ $ git branch -D test <2>
<2> Delete the "test" branch even if the "master" branch (or whichever branch <2> Delete the "test" branch even if the "master" branch (or whichever branch
is currently checked out) does not have all commits from the test branch. is currently checked out) does not have all commits from the test branch.
Listing branches from a specific remote::
+
------------
$ git branch -r -l '<remote>/<pattern>' <1>
$ git for-each-ref 'refs/remotes/<remote>/<pattern>' <2>
------------
+
<1> Using `-a` would conflate <remote> with any local branches you happen to
have been prefixed with the same <remote> pattern.
<2> `for-each-ref` can take a wide range of options. See linkgit:git-for-each-ref[1]
Patterns will normally need quoting.
NOTES NOTES
----- -----
If you are creating a branch that you want to checkout immediately, it is If you are creating a branch that you want to switch to immediately,
easier to use the git checkout command with its `-b` option to create it is easier to use the "git switch" command with its `-c` option to
a branch and check it out with a single command. do the same thing with a single command.
The options `--contains`, `--no-contains`, `--merged` and `--no-merged` The options `--contains`, `--no-contains`, `--merged` and `--no-merged`
serve four related but different purposes: serve four related but different purposes:

View File

@ -88,7 +88,8 @@ but it is explicitly forbidden at the beginning of a branch name).
When run with `--branch` option in a repository, the input is first When run with `--branch` option in a repository, the input is first
expanded for the ``previous checkout syntax'' expanded for the ``previous checkout syntax''
`@{-n}`. For example, `@{-1}` is a way to refer the last thing that `@{-n}`. For example, `@{-1}` is a way to refer the last thing that
was checked out using "git checkout" operation. This option should be was checked out using "git switch" or "git checkout" operation.
This option should be
used by porcelains to accept this syntax anywhere a branch name is used by porcelains to accept this syntax anywhere a branch name is
expected, so they can act as if you typed the branch name. As an expected, so they can act as if you typed the branch name. As an
exception note that, the ``previous checkout operation'' might result exception note that, the ``previous checkout operation'' might result

View File

@ -23,31 +23,22 @@ or the specified tree. If no paths are given, 'git checkout' will
also update `HEAD` to set the specified branch as the current also update `HEAD` to set the specified branch as the current
branch. branch.
'git checkout' <branch>:: 'git checkout' [<branch>]::
To prepare for working on <branch>, switch to it by updating To prepare for working on `<branch>`, switch to it by updating
the index and the files in the working tree, and by pointing the index and the files in the working tree, and by pointing
HEAD at the branch. Local modifications to the files in the `HEAD` at the branch. Local modifications to the files in the
working tree are kept, so that they can be committed to the working tree are kept, so that they can be committed to the
<branch>. `<branch>`.
+ +
If <branch> is not found but there does exist a tracking branch in If `<branch>` is not found but there does exist a tracking branch in
exactly one remote (call it <remote>) with a matching name, treat as exactly one remote (call it `<remote>`) with a matching name and
equivalent to `--no-guess` is not specified, treat as equivalent to
+ +
------------ ------------
$ git checkout -b <branch> --track <remote>/<branch> $ git checkout -b <branch> --track <remote>/<branch>
------------ ------------
+ +
If the branch exists in multiple remotes and one of them is named by You could omit `<branch>`, in which case the command degenerates to
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
You could omit <branch>, in which case the command degenerates to
"check out the current branch", which is a glorified no-op with "check out the current branch", which is a glorified no-op with
rather expensive side-effects to show only the tracking information, rather expensive side-effects to show only the tracking information,
if exists, for the current branch. if exists, for the current branch.
@ -61,7 +52,7 @@ if exists, for the current branch.
`--track` without `-b` implies branch creation; see the `--track` without `-b` implies branch creation; see the
description of `--track` below. description of `--track` below.
+ +
If `-B` is given, <new_branch> is created if it doesn't exist; otherwise, it If `-B` is given, `<new_branch>` is created if it doesn't exist; otherwise, it
is reset. This is the transactional equivalent of is reset. This is the transactional equivalent of
+ +
------------ ------------
@ -75,25 +66,25 @@ successful.
'git checkout' --detach [<branch>]:: 'git checkout' --detach [<branch>]::
'git checkout' [--detach] <commit>:: 'git checkout' [--detach] <commit>::
Prepare to work on top of <commit>, by detaching HEAD at it Prepare to work on top of `<commit>`, by detaching `HEAD` at it
(see "DETACHED HEAD" section), and updating the index and the (see "DETACHED HEAD" section), and updating the index and the
files in the working tree. Local modifications to the files files in the working tree. Local modifications to the files
in the working tree are kept, so that the resulting working in the working tree are kept, so that the resulting working
tree will be the state recorded in the commit plus the local tree will be the state recorded in the commit plus the local
modifications. modifications.
+ +
When the <commit> argument is a branch name, the `--detach` option can When the `<commit>` argument is a branch name, the `--detach` option can
be used to detach HEAD at the tip of the branch (`git checkout be used to detach `HEAD` at the tip of the branch (`git checkout
<branch>` would check out that branch without detaching HEAD). <branch>` would check out that branch without detaching `HEAD`).
+ +
Omitting <branch> detaches HEAD at the tip of the current branch. Omitting `<branch>` detaches `HEAD` at the tip of the current branch.
'git checkout' [<tree-ish>] [--] <pathspec>...:: 'git checkout' [<tree-ish>] [--] <pathspec>...::
Overwrite paths in the working tree by replacing with the Overwrite paths in the working tree by replacing with the
contents in the index or in the <tree-ish> (most often a contents in the index or in the `<tree-ish>` (most often a
commit). When a <tree-ish> is given, the paths that commit). When a `<tree-ish>` is given, the paths that
match the <pathspec> are updated both in the index and in match the `<pathspec>` are updated both in the index and in
the working tree. the working tree.
+ +
The index may contain unmerged entries because of a previous failed merge. The index may contain unmerged entries because of a previous failed merge.
@ -118,7 +109,8 @@ OPTIONS
--quiet:: --quiet::
Quiet, suppress feedback messages. Quiet, suppress feedback messages.
--[no-]progress:: --progress::
--no-progress::
Progress status is reported on the standard error stream Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet` by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not is specified. This flag enables progress reporting even if not
@ -127,7 +119,7 @@ OPTIONS
-f:: -f::
--force:: --force::
When switching branches, proceed even if the index or the When switching branches, proceed even if the index or the
working tree differs from HEAD. This is used to throw away working tree differs from `HEAD`. This is used to throw away
local changes. local changes.
+ +
When checking out paths from the index, do not fail upon unmerged When checking out paths from the index, do not fail upon unmerged
@ -154,12 +146,12 @@ on your side branch as `theirs` (i.e. "one contributor's work on top
of it"). of it").
-b <new_branch>:: -b <new_branch>::
Create a new branch named <new_branch> and start it at Create a new branch named `<new_branch>` and start it at
<start_point>; see linkgit:git-branch[1] for details. `<start_point>`; see linkgit:git-branch[1] for details.
-B <new_branch>:: -B <new_branch>::
Creates the branch <new_branch> and start it at <start_point>; Creates the branch `<new_branch>` and start it at `<start_point>`;
if it already exists, then reset it to <start_point>. This is if it already exists, then reset it to `<start_point>`. This is
equivalent to running "git branch" with "-f"; see equivalent to running "git branch" with "-f"; see
linkgit:git-branch[1] for details. linkgit:git-branch[1] for details.
@ -172,15 +164,36 @@ If no `-b` option is given, the name of the new branch will be
derived from the remote-tracking branch, by looking at the local part of derived from the remote-tracking branch, by looking at the local part of
the refspec configured for the corresponding remote, and then stripping the refspec configured for the corresponding remote, and then stripping
the initial part up to the "*". the initial part up to the "*".
This would tell us to use "hack" as the local branch when branching This would tell us to use `hack` as the local branch when branching
off of "origin/hack" (or "remotes/origin/hack", or even off of `origin/hack` (or `remotes/origin/hack`, or even
"refs/remotes/origin/hack"). If the given name has no slash, or the above `refs/remotes/origin/hack`). If the given name has no slash, or the above
guessing results in an empty name, the guessing is aborted. You can guessing results in an empty name, the guessing is aborted. You can
explicitly give a name with `-b` in such a case. explicitly give a name with `-b` in such a case.
--no-track:: --no-track::
Do not set up "upstream" configuration, even if the Do not set up "upstream" configuration, even if the
branch.autoSetupMerge configuration variable is true. `branch.autoSetupMerge` configuration variable is true.
--guess::
--no-guess::
If `<branch>` is not found but there does exist a tracking
branch in exactly one remote (call it `<remote>`) with a
matching name, treat as equivalent to
+
------------
$ git checkout -b <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to
e.g. `checkout.defaultRemote=origin` to always checkout remote
branches from there if `<branch>` is ambiguous but exists on the
'origin' remote. See also `checkout.defaultRemote` in
linkgit:git-config[1].
+
Use `--no-guess` to disable this.
-l:: -l::
Create the new branch's reflog; see linkgit:git-branch[1] for Create the new branch's reflog; see linkgit:git-branch[1] for
@ -189,21 +202,21 @@ explicitly give a name with `-b` in such a case.
--detach:: --detach::
Rather than checking out a branch to work on it, check out a Rather than checking out a branch to work on it, check out a
commit for inspection and discardable experiments. commit for inspection and discardable experiments.
This is the default behavior of "git checkout <commit>" when This is the default behavior of `git checkout <commit>` when
<commit> is not a branch name. See the "DETACHED HEAD" section `<commit>` is not a branch name. See the "DETACHED HEAD" section
below for details. below for details.
--orphan <new_branch>:: --orphan <new_branch>::
Create a new 'orphan' branch, named <new_branch>, started from Create a new 'orphan' branch, named `<new_branch>`, started from
<start_point> and switch to it. The first commit made on this `<start_point>` and switch to it. The first commit made on this
new branch will have no parents and it will be the root of a new new branch will have no parents and it will be the root of a new
history totally disconnected from all the other branches and history totally disconnected from all the other branches and
commits. commits.
+ +
The index and the working tree are adjusted as if you had previously run The index and the working tree are adjusted as if you had previously run
"git checkout <start_point>". This allows you to start a new history `git checkout <start_point>`. This allows you to start a new history
that records a set of paths similar to <start_point> by easily running that records a set of paths similar to `<start_point>` by easily running
"git commit -a" to make the root commit. `git commit -a` to make the root commit.
+ +
This can be useful when you want to publish the tree from a commit This can be useful when you want to publish the tree from a commit
without exposing its full history. You might want to do this to publish without exposing its full history. You might want to do this to publish
@ -212,17 +225,17 @@ whose full history contains proprietary or otherwise encumbered bits of
code. code.
+ +
If you want to start a disconnected history that records a set of paths If you want to start a disconnected history that records a set of paths
that is totally different from the one of <start_point>, then you should that is totally different from the one of `<start_point>`, then you should
clear the index and the working tree right after creating the orphan clear the index and the working tree right after creating the orphan
branch by running "git rm -rf ." from the top level of the working tree. branch by running `git rm -rf .` from the top level of the working tree.
Afterwards you will be ready to prepare your new files, repopulating the Afterwards you will be ready to prepare your new files, repopulating the
working tree, by copying them from elsewhere, extracting a tarball, etc. working tree, by copying them from elsewhere, extracting a tarball, etc.
--ignore-skip-worktree-bits:: --ignore-skip-worktree-bits::
In sparse checkout mode, `git checkout -- <paths>` would In sparse checkout mode, `git checkout -- <paths>` would
update only entries matched by <paths> and sparse patterns update only entries matched by `<paths>` and sparse patterns
in $GIT_DIR/info/sparse-checkout. This option ignores in `$GIT_DIR/info/sparse-checkout`. This option ignores
the sparse patterns and adds back any files in <paths>. the sparse patterns and adds back any files in `<paths>`.
-m:: -m::
--merge:: --merge::
@ -246,25 +259,25 @@ the conflicted merge in the specified paths.
When switching branches with `--merge`, staged changes may be lost. When switching branches with `--merge`, staged changes may be lost.
--conflict=<style>:: --conflict=<style>::
The same as --merge option above, but changes the way the The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the conflicting hunks are presented, overriding the
merge.conflictStyle configuration variable. Possible values are `merge.conflictStyle` configuration variable. Possible values are
"merge" (default) and "diff3" (in addition to what is shown by "merge" (default) and "diff3" (in addition to what is shown by
"merge" style, shows the original contents). "merge" style, shows the original contents).
-p:: -p::
--patch:: --patch::
Interactively select hunks in the difference between the Interactively select hunks in the difference between the
<tree-ish> (or the index, if unspecified) and the working `<tree-ish>` (or the index, if unspecified) and the working
tree. The chosen hunks are then applied in reverse to the tree. The chosen hunks are then applied in reverse to the
working tree (and if a <tree-ish> was specified, the index). working tree (and if a `<tree-ish>` was specified, the index).
+ +
This means that you can use `git checkout -p` to selectively discard This means that you can use `git checkout -p` to selectively discard
edits from your current working tree. See the ``Interactive Mode'' 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.
+ +
Note that this option uses the no overlay mode by default (see also Note that this option uses the no overlay mode by default (see also
`--[no-]overlay`), and currently doesn't support overlay mode. `--overlay`), and currently doesn't support overlay mode.
--ignore-other-worktrees:: --ignore-other-worktrees::
`git checkout` refuses when the wanted ref is already checked `git checkout` refuses when the wanted ref is already checked
@ -272,38 +285,42 @@ Note that this option uses the no overlay mode by default (see also
out anyway. In other words, the ref can be held by more than one out anyway. In other words, the ref can be held by more than one
worktree. worktree.
--[no-]recurse-submodules:: --overwrite-ignore::
Using --recurse-submodules will update the content of all initialized --no-overwrite-ignore::
Silently overwrite ignored files when switching branches. This
is the default behavior. Use `--no-overwrite-ignore` to abort
the operation when the new branch contains ignored files.
--recurse-submodules::
--no-recurse-submodules::
Using `--recurse-submodules` will update the content of all initialized
submodules according to the commit recorded in the superproject. If submodules according to the commit recorded in the superproject. If
local modifications in a submodule would be overwritten the checkout local modifications in a submodule would be overwritten the checkout
will fail unless `-f` is used. If nothing (or --no-recurse-submodules) will fail unless `-f` is used. If nothing (or `--no-recurse-submodules`)
is used, the work trees of submodules will not be updated. is used, the work trees of submodules will not be updated.
Just like linkgit:git-submodule[1], this will detach the Just like linkgit:git-submodule[1], this will detach `HEAD` of the
submodules HEAD. submodule.
--no-guess:: --overlay::
Do not attempt to create a branch if a remote tracking branch --no-overlay::
of the same name exists.
--[no-]overlay::
In the default overlay mode, `git checkout` never In the default overlay mode, `git checkout` never
removes files from the index or the working tree. When removes files from the index or the working tree. When
specifying `--no-overlay`, files that appear in the index and specifying `--no-overlay`, files that appear in the index and
working tree, but not in <tree-ish> are removed, to make them working tree, but not in `<tree-ish>` are removed, to make them
match <tree-ish> exactly. match `<tree-ish>` exactly.
<branch>:: <branch>::
Branch to checkout; if it refers to a branch (i.e., a name that, Branch to checkout; if it refers to a branch (i.e., a name that,
when prepended with "refs/heads/", is a valid ref), then that when prepended with "refs/heads/", is a valid ref), then that
branch is checked out. Otherwise, if it refers to a valid branch is checked out. Otherwise, if it refers to a valid
commit, your HEAD becomes "detached" and you are no longer on commit, your `HEAD` becomes "detached" and you are no longer on
any branch (see below for details). any branch (see below for details).
+ +
You can use the `"@{-N}"` syntax to refer to the N-th last You can use the `@{-N}` syntax to refer to the N-th last
branch/commit checked out using "git checkout" operation. You may branch/commit checked out using "git checkout" operation. You may
also specify `-` which is synonymous to `"@{-1}"`. also specify `-` which is synonymous to `@{-1}`.
+ +
As a special case, you may use `"A...B"` as a shortcut for the As a 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 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`. leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
@ -312,7 +329,7 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
<start_point>:: <start_point>::
The name of a commit at which to start the new branch; see The name of a commit at which to start the new branch; see
linkgit:git-branch[1] for details. Defaults to HEAD. linkgit:git-branch[1] for details. Defaults to `HEAD`.
+ +
As a special case, you may use `"A...B"` as a shortcut for the As a 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 merge base of `A` and `B` if there is exactly one merge base. You can
@ -326,9 +343,9 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
DETACHED HEAD DETACHED HEAD
------------- -------------
HEAD normally refers to a named branch (e.g. 'master'). Meanwhile, each `HEAD` normally refers to a named branch (e.g. `master`). Meanwhile, each
branch refers to a specific commit. Let's look at a repo with three branch refers to a specific commit. Let's look at a repo with three
commits, one of them tagged, and with branch 'master' checked out: commits, one of them tagged, and with branch `master` checked out:
------------ ------------
HEAD (refers to branch 'master') HEAD (refers to branch 'master')
@ -341,10 +358,10 @@ a---b---c branch 'master' (refers to commit 'c')
------------ ------------
When a commit is created in this state, the branch is updated to refer to When a commit is created in this state, the branch is updated to refer to
the new commit. Specifically, 'git commit' creates a new commit 'd', whose the new commit. Specifically, 'git commit' creates a new commit `d`, whose
parent is commit 'c', and then updates branch 'master' to refer to new parent is commit `c`, and then updates branch `master` to refer to new
commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers commit `d`. `HEAD` still refers to branch `master` and so indirectly now refers
to commit 'd': to commit `d`:
------------ ------------
$ edit; git add; git commit $ edit; git add; git commit
@ -361,7 +378,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
It is sometimes useful to be able to checkout a commit that is not at It is sometimes useful to be able to checkout a commit that is not at
the tip of any named branch, or even to create a new commit that is not the tip of any named branch, or even to create a new commit that is not
referenced by a named branch. Let's look at what happens when we referenced by a named branch. Let's look at what happens when we
checkout commit 'b' (here we show two ways this may be done): checkout commit `b` (here we show two ways this may be done):
------------ ------------
$ git checkout v2.0 # or $ git checkout v2.0 # or
@ -376,9 +393,9 @@ a---b---c---d branch 'master' (refers to commit 'd')
tag 'v2.0' (refers to commit 'b') tag 'v2.0' (refers to commit 'b')
------------ ------------
Notice that regardless of which checkout command we use, HEAD now refers Notice that regardless of which checkout command we use, `HEAD` now refers
directly to commit 'b'. This is known as being in detached HEAD state. directly to commit `b`. This is known as being in detached `HEAD` state.
It means simply that HEAD refers to a specific commit, as opposed to It means simply that `HEAD` refers to a specific commit, as opposed to
referring to a named branch. Let's see what happens when we create a commit: referring to a named branch. Let's see what happens when we create a commit:
------------ ------------
@ -395,7 +412,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
tag 'v2.0' (refers to commit 'b') tag 'v2.0' (refers to commit 'b')
------------ ------------
There is now a new commit 'e', but it is referenced only by HEAD. We can There is now a new commit `e`, but it is referenced only by `HEAD`. We can
of course add yet another commit in this state: of course add yet another commit in this state:
------------ ------------
@ -413,7 +430,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
------------ ------------
In fact, we can perform all the normal Git operations. But, let's look In fact, we can perform all the normal Git operations. But, let's look
at what happens when we then checkout master: at what happens when we then checkout `master`:
------------ ------------
$ git checkout master $ git checkout master
@ -428,9 +445,9 @@ a---b---c---d branch 'master' (refers to commit 'd')
------------ ------------
It is important to realize that at this point nothing refers to commit It is important to realize that at this point nothing refers to commit
'f'. Eventually commit 'f' (and by extension commit 'e') will be deleted `f`. Eventually commit `f` (and by extension commit `e`) will be deleted
by the routine Git garbage collection process, unless we create a reference by the routine Git garbage collection process, unless we create a reference
before that happens. If we have not yet moved away from commit 'f', before that happens. If we have not yet moved away from commit `f`,
any of these will create a reference to it: any of these will create a reference to it:
------------ ------------
@ -439,19 +456,19 @@ $ git branch foo <2>
$ git tag foo <3> $ git tag foo <3>
------------ ------------
<1> creates a new branch 'foo', which refers to commit 'f', and then <1> creates a new branch `foo`, which refers to commit `f`, and then
updates HEAD to refer to branch 'foo'. In other words, we'll no longer updates `HEAD` to refer to branch `foo`. In other words, we'll no longer
be in detached HEAD state after this command. be in detached `HEAD` state after this command.
<2> similarly creates a new branch 'foo', which refers to commit 'f', <2> similarly creates a new branch `foo`, which refers to commit `f`,
but leaves HEAD detached. but leaves `HEAD` detached.
<3> creates a new tag 'foo', which refers to commit 'f', <3> creates a new tag `foo`, which refers to commit `f`,
leaving HEAD detached. leaving `HEAD` detached.
If we have moved away from commit 'f', then we must first recover its object If we have moved away from commit `f`, then we must first recover its object
name (typically by using git reflog), and then we can create a reference to name (typically by using git reflog), and then we can create a reference to
it. For example, to see the last two commits to which HEAD referred, we it. For example, to see the last two commits to which `HEAD` referred, we
can use either of these commands: can use either of these commands:
------------ ------------
@ -462,12 +479,12 @@ $ git log -g -2 HEAD
ARGUMENT DISAMBIGUATION ARGUMENT DISAMBIGUATION
----------------------- -----------------------
When there is only one argument given and it is not `--` (e.g. "git When there is only one argument given and it is not `--` (e.g. `git
checkout abc"), and when the argument is both a valid `<tree-ish>` checkout abc`), and when the argument is both a valid `<tree-ish>`
(e.g. a branch "abc" exists) and a valid `<pathspec>` (e.g. a file (e.g. a branch `abc` exists) and a valid `<pathspec>` (e.g. a file
or a directory whose name is "abc" exists), Git would usually ask or a directory whose name is "abc" exists), Git would usually ask
you to disambiguate. Because checking out a branch is so common an you to disambiguate. Because checking out a branch is so common an
operation, however, "git checkout abc" takes "abc" as a `<tree-ish>` operation, however, `git checkout abc` takes "abc" as a `<tree-ish>`
in such a situation. Use `git checkout -- <pathspec>` if you want in such a situation. Use `git checkout -- <pathspec>` if you want
to checkout these paths out of the index. to checkout these paths out of the index.
@ -475,7 +492,7 @@ EXAMPLES
-------- --------
. The following sequence checks out the `master` branch, reverts . The following sequence checks out the `master` branch, reverts
the `Makefile` to two revisions back, deletes hello.c by the `Makefile` to two revisions back, deletes `hello.c` by
mistake, and gets it back from the index. mistake, and gets it back from the index.
+ +
------------ ------------
@ -487,7 +504,7 @@ $ git checkout hello.c <3>
+ +
<1> switch branch <1> switch branch
<2> take a file out of another commit <2> take a file out of another commit
<3> restore hello.c from the index <3> restore `hello.c` from the index
+ +
If you want to check out _all_ C source files out of the index, If you want to check out _all_ C source files out of the index,
you can say you can say
@ -516,7 +533,7 @@ $ git checkout -- hello.c
$ git checkout mytopic $ git checkout mytopic
------------ ------------
+ +
However, your "wrong" branch and correct "mytopic" branch may However, your "wrong" branch and correct `mytopic` branch may
differ in files that you have modified locally, in which case differ in files that you have modified locally, in which case
the above checkout would fail like this: the above checkout would fail like this:
+ +
@ -557,6 +574,11 @@ $ edit frotz
$ git add frotz $ git add frotz
------------ ------------
SEE ALSO
--------
linkgit:git-switch[1],
linkgit:git-restore[1]
GIT GIT
--- ---
Part of the linkgit:git[1] suite Part of the linkgit:git[1] suite

View File

@ -10,9 +10,7 @@ SYNOPSIS
[verse] [verse]
'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] 'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff]
[-S[<keyid>]] <commit>... [-S[<keyid>]] <commit>...
'git cherry-pick' --continue 'git cherry-pick' (--continue | --skip | --abort | --quit)
'git cherry-pick' --quit
'git cherry-pick' --abort
DESCRIPTION DESCRIPTION
----------- -----------

View File

@ -63,7 +63,7 @@ OPTIONS
still use the ignore rules given with `-e` options from the command still use the ignore rules given with `-e` options from the command
line. This allows removing all untracked line. This allows removing all untracked
files, including build products. This can be used (possibly in files, including build products. This can be used (possibly in
conjunction with 'git reset') to create a pristine conjunction with 'git restore' or 'git reset') to create a pristine
working directory to test a clean build. working directory to test a clean build.
-X:: -X::

View File

@ -15,14 +15,15 @@ SYNOPSIS
[--dissociate] [--separate-git-dir <git dir>] [--dissociate] [--separate-git-dir <git dir>]
[--depth <depth>] [--[no-]single-branch] [--no-tags] [--depth <depth>] [--[no-]single-branch] [--no-tags]
[--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules] [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
[--jobs <n>] [--] <repository> [<directory>] [--[no-]remote-submodules] [--jobs <n>] [--] <repository>
[<directory>]
DESCRIPTION DESCRIPTION
----------- -----------
Clones a repository into a newly created directory, creates Clones a repository into a newly created directory, creates
remote-tracking branches for each branch in the cloned repository remote-tracking branches for each branch in the cloned repository
(visible using `git branch -r`), and creates and checks out an (visible using `git branch --remotes`), and creates and checks out an
initial branch that is forked from the cloned repository's initial branch that is forked from the cloned repository's
currently active branch. currently active branch.
@ -40,8 +41,8 @@ configuration variables.
OPTIONS OPTIONS
------- -------
--local::
-l:: -l::
--local::
When the repository to clone from is on a local machine, When the repository to clone from is on a local machine,
this flag bypasses the normal "Git aware" transport this flag bypasses the normal "Git aware" transport
mechanism and clones the repository by making a copy of mechanism and clones the repository by making a copy of
@ -62,8 +63,8 @@ Git transport instead.
directory instead of using hardlinks. This may be desirable directory instead of using hardlinks. This may be desirable
if you are trying to make a back-up of your repository. if you are trying to make a back-up of your repository.
--shared::
-s:: -s::
--shared::
When the repository to clone is on the local machine, When the repository to clone is on the local machine,
instead of using hard links, automatically setup instead of using hard links, automatically setup
`.git/objects/info/alternates` to share the objects `.git/objects/info/alternates` to share the objects
@ -80,13 +81,13 @@ which automatically call `git gc --auto`. (See linkgit:git-gc[1].)
If these objects are removed and were referenced by the cloned repository, If these objects are removed and were referenced by the cloned repository,
then the cloned repository will become corrupt. then the cloned repository will become corrupt.
+ +
Note that running `git repack` without the `-l` option in a repository Note that running `git repack` without the `--local` option in a repository
cloned with `-s` will copy objects from the source repository into a pack cloned with `--shared` will copy objects from the source repository into a pack
in the cloned repository, removing the disk space savings of `clone -s`. in the cloned repository, removing the disk space savings of `clone --shared`.
It is safe, however, to run `git gc`, which uses the `-l` option by It is safe, however, to run `git gc`, which uses the `--local` option by
default. default.
+ +
If you want to break the dependency of a repository cloned with `-s` on If you want to break the dependency of a repository cloned with `--shared` on
its source repository, you can simply run `git repack -a` to copy all its source repository, you can simply run `git repack -a` to copy all
objects from the source repository into a pack in the cloned repository. objects from the source repository into a pack in the cloned repository.
@ -115,19 +116,19 @@ objects from the source repository into a pack in the cloned repository.
same repository, and this option can be used to stop the same repository, and this option can be used to stop the
borrowing. borrowing.
--quiet::
-q:: -q::
--quiet::
Operate quietly. Progress is not reported to the standard Operate quietly. Progress is not reported to the standard
error stream. error stream.
--verbose::
-v:: -v::
--verbose::
Run verbosely. Does not affect the reporting of progress status Run verbosely. Does not affect the reporting of progress status
to the standard error stream. to the standard error stream.
--progress:: --progress::
Progress status is reported on the standard error stream Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless -q by default when it is attached to a terminal, unless `--quiet`
is specified. This flag forces progress status even if the is specified. This flag forces progress status even if the
standard error stream is not directed to a terminal. standard error stream is not directed to a terminal.
@ -139,15 +140,15 @@ objects from the source repository into a pack in the cloned repository.
When multiple `--server-option=<option>` are given, they are all When multiple `--server-option=<option>` are given, they are all
sent to the other side in the order listed on the command line. sent to the other side in the order listed on the command line.
--no-checkout::
-n:: -n::
--no-checkout::
No checkout of HEAD is performed after the clone is complete. No checkout of HEAD is performed after the clone is complete.
--bare:: --bare::
Make a 'bare' Git repository. That is, instead of Make a 'bare' Git repository. That is, instead of
creating `<directory>` and placing the administrative creating `<directory>` and placing the administrative
files in `<directory>/.git`, make the `<directory>` files in `<directory>/.git`, make the `<directory>`
itself the `$GIT_DIR`. This obviously implies the `-n` itself the `$GIT_DIR`. This obviously implies the `--no-checkout`
because there is nowhere to check out the working tree. because there is nowhere to check out the working tree.
Also the branch heads at the remote are copied directly Also the branch heads at the remote are copied directly
to corresponding local branch heads, without mapping to corresponding local branch heads, without mapping
@ -163,13 +164,13 @@ objects from the source repository into a pack in the cloned repository.
that all these refs are overwritten by a `git remote update` in the that all these refs are overwritten by a `git remote update` in the
target repository. target repository.
--origin <name>::
-o <name>:: -o <name>::
--origin <name>::
Instead of using the remote name `origin` to keep track Instead of using the remote name `origin` to keep track
of the upstream repository, use `<name>`. of the upstream repository, use `<name>`.
--branch <name>::
-b <name>:: -b <name>::
--branch <name>::
Instead of pointing the newly created HEAD to the branch pointed Instead of pointing the newly created HEAD to the branch pointed
to by the cloned repository's HEAD, point to `<name>` branch to by the cloned repository's HEAD, point to `<name>` branch
instead. In a non-bare repository, this is the branch that will instead. In a non-bare repository, this is the branch that will
@ -177,8 +178,8 @@ objects from the source repository into a pack in the cloned repository.
`--branch` can also take tags and detaches the HEAD at that commit `--branch` can also take tags and detaches the HEAD at that commit
in the resulting repository. in the resulting repository.
--upload-pack <upload-pack>::
-u <upload-pack>:: -u <upload-pack>::
--upload-pack <upload-pack>::
When given, and the repository to clone from is accessed When given, and the repository to clone from is accessed
via ssh, this specifies a non-default path for the command via ssh, this specifies a non-default path for the command
run on the other end. run on the other end.
@ -187,8 +188,8 @@ objects from the source repository into a pack in the cloned repository.
Specify the directory from which templates will be used; Specify the directory from which templates will be used;
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].) (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
--config <key>=<value>::
-c <key>=<value>:: -c <key>=<value>::
--config <key>=<value>::
Set a configuration variable in the newly-created repository; Set a configuration variable in the newly-created repository;
this takes effect immediately after the repository is this takes effect immediately after the repository is
initialized, but before the remote history is fetched or any initialized, but before the remote history is fetched or any
@ -260,6 +261,12 @@ or `--mirror` is given)
--[no-]shallow-submodules:: --[no-]shallow-submodules::
All submodules which are cloned will be shallow with a depth of 1. All submodules which are cloned will be shallow with a depth of 1.
--[no-]remote-submodules::
All submodules which are cloned will use the status of the submodules
remote-tracking branch to update the submodule, rather than the
superprojects recorded SHA-1. Equivalent to passing `--remote` to
`git submodule update`.
--separate-git-dir=<git dir>:: --separate-git-dir=<git dir>::
Instead of placing the cloned repository where it is supposed Instead of placing the cloned repository where it is supposed
to be, place the cloned repository at the specified directory, to be, place the cloned repository at the specified directory,

View File

@ -10,7 +10,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git commit-graph read' [--object-dir <dir>] 'git commit-graph read' [--object-dir <dir>]
'git commit-graph verify' [--object-dir <dir>] 'git commit-graph verify' [--object-dir <dir>] [--shallow]
'git commit-graph write' <options> [--object-dir <dir>] 'git commit-graph write' <options> [--object-dir <dir>]
@ -26,7 +26,7 @@ OPTIONS
Use given directory for the location of packfiles and commit-graph Use given directory for the location of packfiles and commit-graph
file. This parameter exists to specify the location of an alternate file. This parameter exists to specify the location of an alternate
that only has the objects directory, not a full `.git` directory. The that only has the objects directory, not a full `.git` directory. The
commit-graph file is expected to be at `<dir>/info/commit-graph` and commit-graph file is expected to be in the `<dir>/info` directory and
the packfiles are expected to be in `<dir>/pack`. the packfiles are expected to be in `<dir>/pack`.
@ -51,6 +51,25 @@ or `--stdin-packs`.)
+ +
With the `--append` option, include all commits that are present in the With the `--append` option, include all commits that are present in the
existing commit-graph file. existing commit-graph file.
+
With the `--split` option, write the commit-graph as a chain of multiple
commit-graph files stored in `<dir>/info/commit-graphs`. The new commits
not already in the commit-graph are added in a new "tip" file. This file
is merged with the existing file if the following merge conditions are
met:
+
* If `--size-multiple=<X>` is not specified, let `X` equal 2. If the new
tip file would have `N` commits and the previous tip has `M` commits and
`X` times `N` is greater than `M`, instead merge the two files into a
single file.
+
* If `--max-commits=<M>` is specified with `M` a positive integer, and the
new tip file would have more than `M` commits, then instead merge the new
tip with the previous tip.
+
Finally, if `--expire-time=<datetime>` is not specified, let `datetime`
be the current time. After writing the split commit-graph, delete all
unused commit-graph whose modified times are older than `datetime`.
'read':: 'read'::
@ -61,6 +80,9 @@ Used for debugging purposes.
Read the commit-graph file and verify its contents against the object Read the commit-graph file and verify its contents against the object
database. Used to check for corrupted data. database. Used to check for corrupted data.
+
With the `--shallow` option, only check the tip commit-graph file in
a chain of split commit-graphs.
EXAMPLES EXAMPLES

View File

@ -359,7 +359,7 @@ When recording your own work, the contents of modified files in
your working tree are temporarily stored to a staging area your working tree are temporarily stored to a staging area
called the "index" with 'git add'. A file can be called the "index" with 'git add'. A file can be
reverted back, only in the index but not in the working tree, 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 restore --staged <file>`,
which effectively reverts 'git add' and prevents the changes to which effectively reverts 'git add' and prevents the changes to
this file from participating in the next commit. After building this file from participating in the next commit. After building
the state to be committed incrementally with these commands, the state to be committed incrementally with these commands,

View File

@ -129,6 +129,13 @@ marks the same across runs.
for intermediary filters (e.g. for rewriting commit messages for intermediary filters (e.g. for rewriting commit messages
which refer to older commits, or for stripping blobs by id). which refer to older commits, or for stripping blobs by id).
--reencode=(yes|no|abort)::
Specify how to handle `encoding` header in commit objects. When
asking to 'abort' (which is the default), this program will die
when encountering such a commit object. With 'yes', the commit
message will be reencoded into UTF-8. With 'no', the original
encoding will be preserved.
--refspec:: --refspec::
Apply the specified refspec to each ref exported. Multiple of them can Apply the specified refspec to each ref exported. Multiple of them can
be specified. be specified.

View File

@ -388,6 +388,7 @@ change to the project.
original-oid? original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)? ('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF 'committer' (SP <name>)? SP LT <email> GT SP <when> LF
('encoding' SP <encoding>)?
data data
('from' SP <commit-ish> LF)? ('from' SP <commit-ish> LF)?
('merge' SP <commit-ish> LF)? ('merge' SP <commit-ish> LF)?
@ -455,6 +456,12 @@ that was selected by the --date-format=<fmt> command-line option.
See ``Date Formats'' above for the set of supported formats, and See ``Date Formats'' above for the set of supported formats, and
their syntax. their syntax.
`encoding`
^^^^^^^^^^
The optional `encoding` command indicates the encoding of the commit
message. Most commits are UTF-8 and the encoding is omitted, but this
allows importing commit messages into git without first reencoding them.
`from` `from`
^^^^^^ ^^^^^^
The `from` command is used to specify the commit to initialize The `from` command is used to specify the commit to initialize

View File

@ -214,6 +214,11 @@ symref::
`:lstrip` and `:rstrip` options in the same way as `refname` `:lstrip` and `:rstrip` options in the same way as `refname`
above. above.
worktreepath::
The absolute path to the worktree in which the ref is checked
out, if it is checked out in any linked worktree. Empty string
otherwise.
In addition to the above, for commit and tag objects, the header In addition to the above, for commit and tag objects, the header
field names (`tree`, `parent`, `object`, `type`, and `tag`) can field names (`tree`, `parent`, `object`, `type`, and `tag`) can
be used to specify the value in the header field. be used to specify the value in the header field.

View File

@ -22,7 +22,8 @@ SYNOPSIS
[--rfc] [--subject-prefix=Subject-Prefix] [--rfc] [--subject-prefix=Subject-Prefix]
[(--reroll-count|-v) <n>] [(--reroll-count|-v) <n>]
[--to=<email>] [--cc=<email>] [--to=<email>] [--cc=<email>]
[--[no-]cover-letter] [--quiet] [--notes[=<ref>]] [--[no-]cover-letter] [--quiet]
[--no-notes | --notes[=<ref>]]
[--interdiff=<previous>] [--interdiff=<previous>]
[--range-diff=<previous> [--creation-factor=<percent>]] [--range-diff=<previous> [--creation-factor=<percent>]]
[--progress] [--progress]
@ -263,6 +264,7 @@ material (this may change in the future).
for details. for details.
--notes[=<ref>]:: --notes[=<ref>]::
--no-notes::
Append the notes (see linkgit:git-notes[1]) for the commit Append the notes (see linkgit:git-notes[1]) for the commit
after the three-dash line. after the three-dash line.
+ +
@ -273,6 +275,9 @@ these explanations after `format-patch` has run but before sending,
keeping them as Git notes allows them to be maintained between versions keeping them as Git notes allows them to be maintained between versions
of the patch series (but see the discussion of the `notes.rewrite` of the patch series (but see the discussion of the `notes.rewrite`
configuration options in linkgit:git-notes[1] to use this workflow). configuration options in linkgit:git-notes[1] to use this workflow).
+
The default is `--no-notes`, unless the `format.notes` configuration is
set.
--[no-]signature=<signature>:: --[no-]signature=<signature>::
Add a signature to each message produced. Per RFC 3676 the signature Add a signature to each message produced. Per RFC 3676 the signature
@ -421,8 +426,8 @@ One way to test if your MUA is set up correctly is:
* Apply it: * Apply it:
$ git fetch <project> master:test-apply $ git fetch <project> master:test-apply
$ git checkout test-apply $ git switch test-apply
$ git reset --hard $ git restore --source=HEAD --staged --worktree :/
$ git am a.patch $ git am a.patch
If it does not apply correctly, there can be various reasons. If it does not apply correctly, there can be various reasons.

View File

@ -18,9 +18,7 @@ Computes the object ID value for an object with specified type
with the contents of the named file (which can be outside of the with the contents of the named file (which can be outside of the
work tree), and optionally writes the resulting object into the work tree), and optionally writes the resulting object into the
object database. Reports its object ID to its standard output. object database. Reports its object ID to its standard output.
This is used by 'git cvsimport' to update the index When <type> is not specified, it defaults to "blob".
without modifying files in the work tree. When <type> is not
specified, it defaults to "blob".
OPTIONS OPTIONS
------- -------

View File

@ -49,7 +49,7 @@ OPTIONS
Print out the ref name given on the command line by which each Print out the ref name given on the command line by which each
commit was reached. commit was reached.
--use-mailmap:: --[no-]use-mailmap::
Use mailmap file to map author and committer names and email Use mailmap file to map author and committer names and email
addresses to canonical real names and email addresses. See addresses to canonical real names and email addresses. See
linkgit:git-shortlog[1]. linkgit:git-shortlog[1].

View File

@ -149,7 +149,7 @@ instead.
Discussion on fork-point mode Discussion on fork-point mode
----------------------------- -----------------------------
After working on the `topic` branch created with `git checkout -b After working on the `topic` branch created with `git switch -c
topic origin/master`, the history of remote-tracking branch topic origin/master`, the history of remote-tracking branch
`origin/master` may have been rewound and rebuilt, leading to a `origin/master` may have been rewound and rebuilt, leading to a
history of this shape: history of this shape:

View File

@ -13,8 +13,7 @@ SYNOPSIS
[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
[--[no-]allow-unrelated-histories] [--[no-]allow-unrelated-histories]
[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>...] [--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>...]
'git merge' --abort 'git merge' (--continue | --abort | --quit)
'git merge' --continue
DESCRIPTION DESCRIPTION
----------- -----------
@ -88,6 +87,11 @@ will be appended to the specified message.
Allow the rerere mechanism to update the index with the Allow the rerere mechanism to update the index with the
result of auto-conflict resolution if possible. result of auto-conflict resolution if possible.
--overwrite-ignore::
--no-overwrite-ignore::
Silently overwrite ignored files from the merge result. This
is the default behavior. Use `--no-overwrite-ignore` to abort.
--abort:: --abort::
Abort the current conflict resolution process, and Abort the current conflict resolution process, and
try to reconstruct the pre-merge state. try to reconstruct the pre-merge state.
@ -100,6 +104,10 @@ commit or stash your changes before running 'git merge'.
'git merge --abort' is equivalent to 'git reset --merge' when 'git merge --abort' is equivalent to 'git reset --merge' when
`MERGE_HEAD` is present. `MERGE_HEAD` is present.
--quit::
Forget about the current merge in progress. Leave the index
and the working tree as-is.
--continue:: --continue::
After a 'git merge' stops due to conflicts you can conclude the After a 'git merge' stops due to conflicts you can conclude the
merge by running 'git merge --continue' (see "HOW TO RESOLVE merge by running 'git merge --continue' (see "HOW TO RESOLVE

View File

@ -9,7 +9,7 @@ git-multi-pack-index - Write and verify multi-pack-indexes
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git multi-pack-index' [--object-dir=<dir>] <verb> 'git multi-pack-index' [--object-dir=<dir>] <subcommand>
DESCRIPTION DESCRIPTION
----------- -----------
@ -23,13 +23,35 @@ OPTIONS
`<dir>/packs/multi-pack-index` for the current MIDX file, and `<dir>/packs/multi-pack-index` for the current MIDX file, and
`<dir>/packs` for the pack-files to index. `<dir>/packs` for the pack-files to index.
The following subcommands are available:
write:: write::
When given as the verb, write a new MIDX file to Write a new MIDX file.
`<dir>/packs/multi-pack-index`.
verify:: verify::
When given as the verb, verify the contents of the MIDX file Verify the contents of the MIDX file.
at `<dir>/packs/multi-pack-index`.
expire::
Delete the pack-files that are tracked by the MIDX file, but
have no objects referenced by the MIDX. Rewrite the MIDX file
afterward to remove all references to these pack-files.
repack::
Create a new pack-file containing objects in small pack-files
referenced by the multi-pack-index. If the size given by the
`--batch-size=<size>` argument is zero, then create a pack
containing all objects referenced by the multi-pack-index. For
a non-zero batch size, Select the pack-files by examining packs
from oldest-to-newest, computing the "expected size" by counting
the number of objects in the pack referenced by the
multi-pack-index, then divide by the total number of objects in
the pack and multiply by the pack size. We select packs with
expected size below the batch size until the set of packs have
total expected size at least the batch size. If the total size
does not reach the batch size, then do nothing. If a new pack-
file is created, rewrite the multi-pack-index to reference the
new pack-file. A later run of 'git multi-pack-index expire' will
delete the pack-files that were part of this batch.
EXAMPLES EXAMPLES

View File

@ -12,12 +12,12 @@ SYNOPSIS
[<upstream> [<branch>]] [<upstream> [<branch>]]
'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] 'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
--root [<branch>] --root [<branch>]
'git rebase' --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch 'git rebase' (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)
DESCRIPTION DESCRIPTION
----------- -----------
If <branch> is specified, 'git rebase' will perform an automatic If <branch> is specified, 'git rebase' will perform an automatic
`git checkout <branch>` before doing anything else. Otherwise `git switch <branch>` before doing anything else. Otherwise
it remains on the current branch. it remains on the current branch.
If <upstream> is not specified, the upstream configured in If <upstream> is not specified, the upstream configured in

View File

@ -230,7 +230,7 @@ $ git branch -r
staging/master staging/master
staging/staging-linus staging/staging-linus
staging/staging-next staging/staging-next
$ git checkout -b staging staging/master $ git switch -c staging staging/master
... ...
------------ ------------

View File

@ -91,7 +91,7 @@ For such a test, you need to merge master and topic somehow.
One way to do it is to pull master into the topic branch: One way to do it is to pull master into the topic branch:
------------ ------------
$ git checkout topic $ git switch topic
$ git merge master $ git merge master
o---*---o---+ topic o---*---o---+ topic
@ -113,10 +113,10 @@ the upstream might have been advanced since the test merge `+`,
in which case the final commit graph would look like this: in which case the final commit graph would look like this:
------------ ------------
$ git checkout topic $ git switch topic
$ git merge master $ git merge master
$ ... work on both topic and master branches $ ... work on both topic and master branches
$ git checkout master $ git switch master
$ git merge topic $ git merge topic
o---*---o---+---o---o topic o---*---o---+---o---o topic
@ -136,11 +136,11 @@ merges, you could blow away the test merge, and keep building on
top of the tip before the test merge: top of the tip before the test merge:
------------ ------------
$ git checkout topic $ git switch topic
$ git merge master $ git merge master
$ git reset --hard HEAD^ ;# rewind the test merge $ git reset --hard HEAD^ ;# rewind the test merge
$ ... work on both topic and master branches $ ... work on both topic and master branches
$ git checkout master $ git switch master
$ git merge topic $ git merge topic
o---*---o-------o---o topic o---*---o-------o---o topic

View File

@ -25,12 +25,13 @@ The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms.
the current branch.) the current branch.)
+ +
This means that `git reset <paths>` is the opposite of `git add This means that `git reset <paths>` is the opposite of `git add
<paths>`. <paths>`. This command is equivalent to
`git restore [--source=<tree-ish>] --staged <paths>...`.
+ +
After running `git reset <paths>` to update the index entry, you can After running `git reset <paths>` to update the index entry, you can
use linkgit:git-checkout[1] to check the contents out of the index to use linkgit:git-restore[1] to check the contents out of the index to
the working tree. the working tree. Alternatively, using linkgit:git-restore[1]
Alternatively, using linkgit:git-checkout[1] and specifying a commit, you and specifying a commit with `--source`, you
can copy the contents of a path out of a commit to the index and to the can copy the contents of a path out of a commit to the index and to the
working tree in one go. working tree in one go.
@ -86,8 +87,8 @@ but carries forward unmerged index entries.
changes, reset is aborted. changes, reset is aborted.
-- --
If you want to undo a commit other than the latest on a branch, See "Reset, restore and revert" in linkgit:git[1] for the differences
linkgit:git-revert[1] is your friend. between the three commands.
OPTIONS OPTIONS
@ -151,7 +152,7 @@ Undo a commit, making it a topic branch::
------------ ------------
$ git branch topic/wip <1> $ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2> $ git reset --hard HEAD~3 <2>
$ git checkout topic/wip <3> $ git switch topic/wip <3>
------------ ------------
+ +
<1> You have made some commits, but realize they were premature <1> You have made some commits, but realize they were premature
@ -232,13 +233,13 @@ working tree are not in any shape to be committed yet, but you
need to get to the other branch for a quick bugfix. need to get to the other branch for a quick bugfix.
+ +
------------ ------------
$ git checkout feature ;# you were working in "feature" branch and $ git switch feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted $ work work work ;# got interrupted
$ git commit -a -m "snapshot WIP" <1> $ git commit -a -m "snapshot WIP" <1>
$ git checkout master $ git switch master
$ fix fix fix $ fix fix fix
$ git commit ;# commit with real log $ git commit ;# commit with real log
$ git checkout feature $ git switch feature
$ git reset --soft HEAD^ ;# go back to WIP state <2> $ git reset --soft HEAD^ ;# go back to WIP state <2>
$ git reset <3> $ git reset <3>
------------ ------------
@ -279,18 +280,18 @@ reset it while keeping the changes in your working tree.
+ +
------------ ------------
$ git tag start $ git tag start
$ git checkout -b branch1 $ git switch -c branch1
$ edit $ edit
$ git commit ... <1> $ git commit ... <1>
$ edit $ edit
$ git checkout -b branch2 <2> $ git switch -c branch2 <2>
$ git reset --keep start <3> $ git reset --keep start <3>
------------ ------------
+ +
<1> This commits your first edits in `branch1`. <1> This commits your first edits in `branch1`.
<2> In the ideal world, you could have realized that the earlier <2> In the ideal world, you could have realized that the earlier
commit did not belong to the new topic when you created and switched commit did not belong to the new topic when you created and switched
to `branch2` (i.e. `git checkout -b branch2 start`), but nobody is to `branch2` (i.e. `git switch -c branch2 start`), but nobody is
perfect. perfect.
<3> But you can use `reset --keep` to remove the unwanted commit after <3> But you can use `reset --keep` to remove the unwanted commit after
you switched to `branch2`. you switched to `branch2`.

View File

@ -0,0 +1,185 @@
git-restore(1)
==============
NAME
----
git-restore - Restore working tree files
SYNOPSIS
--------
[verse]
'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] <pathspec>...
'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [<pathspec>...]
DESCRIPTION
-----------
Restore specified paths in the working tree with some contents from a
restore source. If a path is tracked but does not exist in the restore
source, it will be removed to match the source.
The command can also be used to restore the content in the index with
`--staged`, or restore both the working tree and the index with
`--staged --worktree`.
By default, the restore sources for working tree and the index are the
index and `HEAD` respectively. `--source` could be used to specify a
commit as the restore source.
See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
OPTIONS
-------
-s <tree>::
--source=<tree>::
Restore the working tree files with the content from the given
tree. It is common to specify the source tree by naming a
commit, branch or tag associated with it.
+
If not specified, the default restore source for the working tree is
the index, and the default restore source for the index index is
`HEAD`. When both `--staged` and `--worktree` are specified,
`--source` must also be specified.
-p::
--patch::
Interactively select hunks in the difference between the
restore source and the restore location. See the ``Interactive
Mode'' section of linkgit:git-add[1] to learn how to operate
the `--patch` mode.
+
Note that `--patch` can accept no pathspec and will prompt to restore
all modified paths.
-W::
--worktree::
-S::
--staged::
Specify the restore location. If neither option is specified,
by default the working tree is restored. Specifying `--staged`
will only restore the index. Specifying both restores both.
-q::
--quiet::
Quiet, suppress feedback messages. Implies `--no-progress`.
--progress::
--no-progress::
Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not
attached to a terminal, regardless of `--quiet`.
--ours::
--theirs::
When restoring files in the working tree from the index, use
stage #2 ('ours') or #3 ('theirs') for unmerged paths.
+
Note that during `git rebase` and `git pull --rebase`, 'ours' and
'theirs' may appear swapped. See the explanation of the same options
in linkgit:git-checkout[1] for details.
-m::
--merge::
When restoring files on the working tree from the index,
recreate the conflicted merge in the unmerged paths.
--conflict=<style>::
The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the
`merge.conflictStyle` configuration variable. Possible values
are "merge" (default) and "diff3" (in addition to what is
shown by "merge" style, shows the original contents).
--ignore-unmerged::
When restoring files on the working tree from the index, do
not abort the operation if there are unmerged entries and
neither `--ours`, `--theirs`, `--merge` or `--conflict` is
specified. Unmerged paths on the working tree are left alone.
--ignore-skip-worktree-bits::
In sparse checkout mode, by default is to only update entries
matched by `<pathspec>` and sparse patterns in
$GIT_DIR/info/sparse-checkout. This option ignores the sparse
patterns and unconditionally restores any files in
`<pathspec>`.
--overlay::
--no-overlay::
In overlay mode, the command never removes files when
restoring. In no-overlay mode, tracked files that do not
appear in the `--source` tree are removed, to make them match
`<tree>` exactly. The default is no-overlay mode.
EXAMPLES
--------
The following sequence switches to the `master` branch, reverts the
`Makefile` to two revisions back, deletes hello.c by mistake, and gets
it back from the index.
------------
$ git switch master
$ git restore --source master~2 Makefile <1>
$ rm -f hello.c
$ git restore hello.c <2>
------------
<1> take a file out of another commit
<2> restore hello.c from the index
If you want to restore _all_ C source files to match the version in
the index, you can say
------------
$ git restore '*.c'
------------
Note the quotes around `*.c`. The file `hello.c` will also be
restored, even though it is no longer in the working tree, because the
file globbing is used to match entries in the index (not in the
working tree by the shell).
To restore all files in the current directory
------------
$ git restore .
------------
or to restore all working tree files with 'top' pathspec magic (see
linkgit:gitglossary[7])
------------
$ git restore :/
------------
To restore a file in the index to match the version in `HEAD` (this is
the same as using linkgit:git-reset[1])
------------
$ git restore --staged hello.c
------------
or you can restore both the index and the working tree (this the same
as using linkgit:git-checkout[1])
------------
$ git restore --source=HEAD --staged --worktree hello.c
------------
or the short form which is more practical but less readable:
------------
$ git restore -s@ -SW hello.c
------------
SEE ALSO
--------
linkgit:git-checkout[1],
linkgit:git-reset[1]
GIT
---
Part of the linkgit:git[1] suite

View File

@ -48,6 +48,7 @@ SYNOPSIS
[ --date=<format>] [ --date=<format>]
[ [ --objects | --objects-edge | --objects-edge-aggressive ] [ [ --objects | --objects-edge | --objects-edge-aggressive ]
[ --unpacked ] [ --unpacked ]
[ --object-names | --no-object-names ]
[ --filter=<filter-spec> [ --filter-print-omitted ] ] ] [ --filter=<filter-spec> [ --filter-print-omitted ] ] ]
[ --missing=<missing-action> ] [ --missing=<missing-action> ]
[ --pretty | --header ] [ --pretty | --header ]

View File

@ -9,9 +9,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>... 'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>...
'git revert' --continue 'git revert' (--continue | --skip | --abort | --quit)
'git revert' --quit
'git revert' --abort
DESCRIPTION DESCRIPTION
----------- -----------
@ -26,10 +24,13 @@ effect of some earlier commits (often only a faulty one). If you want to
throw away all uncommitted changes in your working directory, you throw away all uncommitted changes in your working directory, you
should see linkgit:git-reset[1], particularly the `--hard` option. If should see linkgit:git-reset[1], particularly the `--hard` option. If
you want to extract specific files as they were in another commit, you you want to extract specific files as they were in another commit, you
should see linkgit:git-checkout[1], specifically the `git checkout should see linkgit:git-restore[1], specifically the `--source`
<commit> -- <filename>` syntax. Take care with these alternatives as option. Take care with these alternatives as
both will discard uncommitted changes in your working directory. both will discard uncommitted changes in your working directory.
See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.
OPTIONS OPTIONS
------- -------
<commit>...:: <commit>...::

View File

@ -278,6 +278,14 @@ must be used for each option.
Automating Automating
~~~~~~~~~~ ~~~~~~~~~~
--no-[to|cc|bcc]::
Clears any list of "To:", "Cc:", "Bcc:" addresses previously
set via config.
--no-identity::
Clears the previously read value of `sendemail.identity` set
via config, if any.
--to-cmd=<command>:: --to-cmd=<command>::
Specify a command to execute once per patch file which Specify a command to execute once per patch file which
should generate patch file specific "To:" entries. should generate patch file specific "To:" entries.
@ -500,8 +508,12 @@ app-specific or your regular password as appropriate. If you have credential
helper configured (see linkgit:git-credential[1]), the password will be saved in helper configured (see linkgit:git-credential[1]), the password will be saved in
the credential store so you won't have to type it the next time. the credential store so you won't have to type it the next time.
Note: the following perl modules are required Note: the following core Perl modules that may be installed with your
Net::SMTP::SSL, MIME::Base64 and Authen::SASL distribution of Perl are required:
MIME::Base64, MIME::QuotedPrint, Net::Domain and Net::SMTP.
These additional Perl modules are also required:
Authen::SASL and Mail::Address.
SEE ALSO SEE ALSO
-------- --------

View File

@ -235,12 +235,12 @@ return to your original branch to make the emergency fix, like this:
+ +
---------------------------------------------------------------- ----------------------------------------------------------------
# ... hack hack hack ... # ... hack hack hack ...
$ git checkout -b my_wip $ git switch -c my_wip
$ git commit -a -m "WIP" $ git commit -a -m "WIP"
$ git checkout master $ git switch master
$ edit emergency fix $ edit emergency fix
$ git commit -a -m "Fix in a hurry" $ git commit -a -m "Fix in a hurry"
$ git checkout my_wip $ git switch my_wip
$ git reset --soft HEAD^ $ git reset --soft HEAD^
# ... continue hacking ... # ... continue hacking ...
---------------------------------------------------------------- ----------------------------------------------------------------
@ -293,7 +293,8 @@ SEE ALSO
linkgit:git-checkout[1], linkgit:git-checkout[1],
linkgit:git-commit[1], linkgit:git-commit[1],
linkgit:git-reflog[1], linkgit:git-reflog[1],
linkgit:git-reset[1] linkgit:git-reset[1],
linkgit:git-switch[1]
GIT GIT
--- ---

View File

@ -0,0 +1,273 @@
git-switch(1)
=============
NAME
----
git-switch - Switch branches
SYNOPSIS
--------
[verse]
'git switch' [<options>] [--no-guess] <branch>
'git switch' [<options>] --detach [<start-point>]
'git switch' [<options>] (-c|-C) <new-branch> [<start-point>]
'git switch' [<options>] --orphan <new-branch>
DESCRIPTION
-----------
Switch to a specified branch. The working tree and the index are
updated to match the branch. All new commits will be added to the tip
of this branch.
Optionally a new branch could be created with either `-c`, `-C`,
automatically from a remote branch of same name (see `--guess`), or
detach the working tree from any branch with `--detach`, along with
switching.
Switching branches does not require a clean index and working tree
(i.e. no differences compared to `HEAD`). The operation is aborted
however if the operation leads to loss of local changes, unless told
otherwise with `--discard-changes` or `--merge`.
THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
OPTIONS
-------
<branch>::
Branch to switch to.
<new-branch>::
Name for the new branch.
<start-point>::
The starting point for the new branch. Specifying a
`<start-point>` allows you to create a branch based on some
other point in history than where HEAD currently points. (Or,
in the case of `--detach`, allows you to inspect and detach
from some other point.)
+
You can use the `@{-N}` syntax to refer to the N-th last
branch/commit switched to using "git switch" or "git checkout"
operation. You may also specify `-` which is synonymous to `@{-1}`.
This is often used to switch quickly between two branches, or to undo
a branch switch by mistake.
+
As a 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`.
-c <new-branch>::
--create <new-branch>::
Create a new branch named `<new-branch>` starting at
`<start-point>` before switching to the branch. This is a
convenient shortcut for:
+
------------
$ git branch <new-branch>
$ git switch <new-branch>
------------
-C <new-branch>::
--force-create <new-branch>::
Similar to `--create` except that if `<new-branch>` already
exists, it will be reset to `<start-point>`. This is a
convenient shortcut for:
+
------------
$ git branch -f <new-branch>
$ git switch <new-branch>
------------
-d::
--detach::
Switch to a commit for inspection and discardable
experiments. See the "DETACHED HEAD" section in
linkgit:git-checkout[1] for details.
--guess::
--no-guess::
If `<branch>` is not found but there does exist a tracking
branch in exactly one remote (call it `<remote>`) with a
matching name, treat as equivalent to
+
------------
$ git switch -c <branch> --track <remote>/<branch>
------------
+
If the branch exists in multiple remotes and one of them is named by
the `checkout.defaultRemote` configuration variable, we'll use that
one for the purposes of disambiguation, even if the `<branch>` isn't
unique across all remotes. Set it to e.g. `checkout.defaultRemote=origin`
to always checkout remote branches from there if `<branch>` is
ambiguous but exists on the 'origin' remote. See also
`checkout.defaultRemote` in linkgit:git-config[1].
+
`--guess` is the default behavior. Use `--no-guess` to disable it.
-f::
--force::
An alias for `--discard-changes`.
--discard-changes::
Proceed even if the index or the working tree differs from
`HEAD`. Both the index and working tree are restored to match
the switching target. If `--recurse-submodules` is specified,
submodule content is also restored to match the switching
target. This is used to throw away local changes.
-m::
--merge::
If you have local modifications to one or more files that are
different between the current branch and the branch to which
you are switching, the command refuses to switch branches in
order to preserve your modifications in context. However,
with this option, a three-way merge between the current
branch, your working tree contents, and the new branch is
done, and you will be on the new branch.
+
When a merge conflict happens, the index entries for conflicting
paths are left unmerged, and you need to resolve the conflicts
and mark the resolved paths with `git add` (or `git rm` if the merge
should result in deletion of the path).
--conflict=<style>::
The same as `--merge` option above, but changes the way the
conflicting hunks are presented, overriding the
`merge.conflictStyle` configuration variable. Possible values are
"merge" (default) and "diff3" (in addition to what is shown by
"merge" style, shows the original contents).
-q::
--quiet::
Quiet, suppress feedback messages.
--progress::
--no-progress::
Progress status is reported on the standard error stream
by default when it is attached to a terminal, unless `--quiet`
is specified. This flag enables progress reporting even if not
attached to a terminal, regardless of `--quiet`.
-t::
--track::
When creating a new branch, set up "upstream" configuration.
`-c` is implied. See `--track` in linkgit:git-branch[1] for
details.
+
If no `-c` option is given, the name of the new branch will be derived
from the remote-tracking branch, by looking at the local part of the
refspec configured for the corresponding remote, and then stripping
the initial part up to the "*". This would tell us to use `hack` as
the local branch when branching off of `origin/hack` (or
`remotes/origin/hack`, or even `refs/remotes/origin/hack`). If the
given name has no slash, or the above guessing results in an empty
name, the guessing is aborted. You can explicitly give a name with
`-c` in such a case.
--no-track::
Do not set up "upstream" configuration, even if the
`branch.autoSetupMerge` configuration variable is true.
--orphan <new-branch>::
Create a new 'orphan' branch, named `<new-branch>`. All
tracked files are removed.
--ignore-other-worktrees::
`git switch` refuses when the wanted ref is already
checked out by another worktree. This option makes it check
the ref out anyway. In other words, the ref can be held by
more than one worktree.
--recurse-submodules::
--no-recurse-submodules::
Using `--recurse-submodules` will update the content of all
initialized submodules according to the commit recorded in the
superproject. If nothing (or `--no-recurse-submodules`) is
used, the work trees of submodules will not be updated. Just
like linkgit:git-submodule[1], this will detach `HEAD` of the
submodules.
EXAMPLES
--------
The following command switches to the "master" branch:
------------
$ git switch master
------------
After working in the wrong branch, switching to the correct branch
would be done using:
------------
$ git switch mytopic
------------
However, your "wrong" branch and correct "mytopic" branch may differ
in files that you have modified locally, in which case the above
switch would fail like this:
------------
$ git switch mytopic
error: You have local changes to 'frotz'; not switching branches.
------------
You can give the `-m` flag to the command, which would try a three-way
merge:
------------
$ git switch -m mytopic
Auto-merging frotz
------------
After this three-way merge, the local modifications are _not_
registered in your index file, so `git diff` would show you what
changes you made since the tip of the new branch.
To switch back to the previous branch before we switched to mytopic
(i.e. "master" branch):
------------
$ git switch -
------------
You can grow a new branch from any commit. For example, switch to
"HEAD~3" and create branch "fixup":
------------
$ git switch -c fixup HEAD~3
Switched to a new branch 'fixup'
------------
If you want to start a new branch from a remote branch of the same
name:
------------
$ git switch new-topic
Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin'
Switched to a new branch 'new-topic'
------------
To check out commit `HEAD~3` for temporary inspection or experiment
without creating a new branch:
------------
$ git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
------------
If it turns out whatever you have done is worth keeping, you can
always create a new name for it (without switching away):
------------
$ git switch -c good-surprises
------------
SEE ALSO
--------
linkgit:git-checkout[1],
linkgit:git-branch[1]
GIT
---
Part of the linkgit:git[1] suite

View File

@ -64,6 +64,13 @@ OPTIONS
-s:: -s::
--sign:: --sign::
Make a GPG-signed tag, using the default e-mail address's key. Make a GPG-signed tag, using the default e-mail address's key.
The default behavior of tag GPG-signing is controlled by `tag.gpgSign`
configuration variable if it exists, or disabled oder otherwise.
See linkgit:git-config[1].
--no-sign::
Override `tag.gpgSign` configuration variable that is
set to force each and every tag to be signed.
-u <keyid>:: -u <keyid>::
--local-user=<keyid>:: --local-user=<keyid>::

View File

@ -9,7 +9,7 @@ git-update-server-info - Update auxiliary info file to help dumb servers
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git update-server-info' [--force] 'git update-server-info'
DESCRIPTION DESCRIPTION
----------- -----------
@ -19,15 +19,6 @@ $GIT_OBJECT_DIRECTORY/info directories to help clients discover
what references and packs the server has. This command what references and packs the server has. This command
generates such auxiliary files. generates such auxiliary files.
OPTIONS
-------
-f::
--force::
Update the info files from scratch.
OUTPUT OUTPUT
------ ------

View File

@ -33,7 +33,8 @@ individual Git commands with "git help command". linkgit:gitcli[7]
manual page gives you an overview of the command-line command syntax. manual page gives you an overview of the command-line command syntax.
A formatted and hyperlinked copy of the latest Git documentation A formatted and hyperlinked copy of the latest Git documentation
can be viewed at `https://git.github.io/htmldocs/git.html`. can be viewed at https://git.github.io/htmldocs/git.html
or https://git-scm.com/docs.
OPTIONS OPTIONS
@ -56,7 +57,8 @@ help ...`.
Run as if git was started in '<path>' instead of the current working Run as if git was started in '<path>' instead of the current working
directory. When multiple `-C` options are given, each subsequent directory. When multiple `-C` options are given, each subsequent
non-absolute `-C <path>` is interpreted relative to the preceding `-C non-absolute `-C <path>` is interpreted relative to the preceding `-C
<path>`. <path>`. If '<path>' is present but empty, e.g. `-C ""`, then the
current working directory is left unchanged.
+ +
This option affects options that expect path name like `--git-dir` and This option affects options that expect path name like `--git-dir` and
`--work-tree` in that their interpretations of the path names would be `--work-tree` in that their interpretations of the path names would be
@ -210,6 +212,26 @@ people via patch over e-mail.
include::cmds-foreignscminterface.txt[] include::cmds-foreignscminterface.txt[]
Reset, restore and revert
~~~~~~~~~~~~~~~~~~~~~~~~~
There are three commands with similar names: `git reset`,
`git restore` and `git revert`.
* linkgit:git-revert[1] is about making a new commit that reverts the
changes made by other commits.
* linkgit:git-restore[1] is about restoring files in the working tree
from either the index or another commit. This command does not
update your branch. The command can also be used to restore files in
the index from another commit.
* linkgit:git-reset[1] is about updating your branch, moving the tip
in order to add or remove commits from the branch. This operation
changes the commit history.
+
`git reset` can also be used to restore the index, overlapping with
`git restore`.
Low-level commands (plumbing) Low-level commands (plumbing)
----------------------------- -----------------------------

View File

@ -112,7 +112,8 @@ Checking-out and checking-in
These attributes affect how the contents stored in the These attributes affect how the contents stored in the
repository are copied to the working tree files when commands repository are copied to the working tree files when commands
such as 'git checkout' and 'git merge' run. They also affect how such as 'git switch', 'git checkout' and 'git merge' run.
They also affect how
Git stores the contents you prepare in the working tree in the Git stores the contents you prepare in the working tree in the
repository upon 'git add' and 'git commit'. repository upon 'git add' and 'git commit'.
@ -819,7 +820,7 @@ patterns are available:
- `java` suitable for source code in the Java language. - `java` suitable for source code in the Java language.
- `matlab` suitable for source code in the MATLAB language. - `matlab` suitable for source code in the MATLAB and Octave languages.
- `objc` suitable for source code in the Objective-C language. - `objc` suitable for source code in the Objective-C language.
@ -833,6 +834,8 @@ patterns are available:
- `ruby` suitable for source code in the Ruby language. - `ruby` suitable for source code in the Ruby language.
- `rust` suitable for source code in the Rust language.
- `tex` suitable for source code for LaTeX documents. - `tex` suitable for source code for LaTeX documents.

View File

@ -47,8 +47,8 @@ disambiguating `--` at appropriate places.
things: things:
+ +
-------------------------------- --------------------------------
$ git checkout -- *.c $ git restore *.c
$ git checkout -- \*.c $ git restore \*.c
-------------------------------- --------------------------------
+ +
The former lets your shell expand the fileglob, and you are asking The former lets your shell expand the fileglob, and you are asking
@ -209,6 +209,18 @@ See also http://marc.info/?l=git&m=116563135620359 and
http://marc.info/?l=git&m=119150393620273 for further http://marc.info/?l=git&m=119150393620273 for further
information. information.
Some other commands that also work on files in the working tree and/or
in the index can take `--staged` and/or `--worktree`.
* `--staged` is exactly like `--cached`, which is used to ask a
command to only work on the index, not the working tree.
* `--worktree` is the opposite, to ask a command to work on the
working tree only, not the index.
* The two options can be specified together to ask a command to work
on both the index and the working tree.
GIT GIT
--- ---
Part of the linkgit:git[1] suite Part of the linkgit:git[1] suite

View File

@ -741,7 +741,7 @@ used earlier, and create a branch in it. You do that by simply just
saying that you want to check out a new branch: saying that you want to check out a new branch:
------------ ------------
$ git checkout -b mybranch $ git switch -c mybranch
------------ ------------
will create a new branch based at the current `HEAD` position, and switch will create a new branch based at the current `HEAD` position, and switch
@ -755,7 +755,7 @@ just telling 'git checkout' what the base of the checkout would be.
In other words, if you have an earlier tag or branch, you'd just do In other words, if you have an earlier tag or branch, you'd just do
------------ ------------
$ git checkout -b mybranch earlier-commit $ git switch -c mybranch earlier-commit
------------ ------------
and it would create the new branch `mybranch` at the earlier commit, and it would create the new branch `mybranch` at the earlier commit,
@ -765,7 +765,7 @@ and check out the state at that time.
You can always just jump back to your original `master` branch by doing You can always just jump back to your original `master` branch by doing
------------ ------------
$ git checkout master $ git switch master
------------ ------------
(or any other branch-name, for that matter) and if you forget which (or any other branch-name, for that matter) and if you forget which
@ -794,7 +794,7 @@ $ git branch <branchname> [startingpoint]
which will simply _create_ the branch, but will not do anything further. which will simply _create_ the branch, but will not do anything further.
You can then later -- once you decide that you want to actually develop You can then later -- once you decide that you want to actually develop
on that branch -- switch to that branch with a regular 'git checkout' on that branch -- switch to that branch with a regular 'git switch'
with the branchname as the argument. with the branchname as the argument.
@ -808,7 +808,7 @@ being the same as the original `master` branch, let's make sure we're in
that branch, and do some work there. that branch, and do some work there.
------------------------------------------------ ------------------------------------------------
$ git checkout mybranch $ git switch mybranch
$ echo "Work, work, work" >>hello $ echo "Work, work, work" >>hello
$ git commit -m "Some work." -i hello $ git commit -m "Some work." -i hello
------------------------------------------------ ------------------------------------------------
@ -825,7 +825,7 @@ does some work in the original branch, and simulate that by going back
to the master branch, and editing the same file differently there: to the master branch, and editing the same file differently there:
------------ ------------
$ git checkout master $ git switch master
------------ ------------
Here, take a moment to look at the contents of `hello`, and notice how they Here, take a moment to look at the contents of `hello`, and notice how they
@ -958,7 +958,7 @@ to the `master` branch. Let's go back to `mybranch`, and run
'git merge' to get the "upstream changes" back to your branch. 'git merge' to get the "upstream changes" back to your branch.
------------ ------------
$ git checkout mybranch $ git switch mybranch
$ git merge -m "Merge upstream changes." master $ git merge -m "Merge upstream changes." master
------------ ------------
@ -1133,9 +1133,8 @@ Remember, before running 'git merge', our `master` head was at
work." commit. work." commit.
------------ ------------
$ git checkout mybranch $ git switch -C mybranch master^2
$ git reset --hard master^2 $ git switch master
$ git checkout master
$ git reset --hard master^ $ git reset --hard master^
------------ ------------

View File

@ -41,7 +41,7 @@ following commands.
* linkgit:git-log[1] to see what happened. * linkgit:git-log[1] to see what happened.
* linkgit:git-checkout[1] and linkgit:git-branch[1] to switch * linkgit:git-switch[1] and linkgit:git-branch[1] to switch
branches. branches.
* linkgit:git-add[1] to manage the index file. * linkgit:git-add[1] to manage the index file.
@ -51,8 +51,7 @@ following commands.
* linkgit:git-commit[1] to advance the current branch. * linkgit:git-commit[1] to advance the current branch.
* linkgit:git-reset[1] and linkgit:git-checkout[1] (with * linkgit:git-restore[1] to undo changes.
pathname parameters) to undo changes.
* linkgit:git-merge[1] to merge between local branches. * linkgit:git-merge[1] to merge between local branches.
@ -80,9 +79,9 @@ $ git tag v2.43 <2>
Create a topic branch and develop.:: Create a topic branch and develop.::
+ +
------------ ------------
$ git checkout -b alsa-audio <1> $ git switch -c alsa-audio <1>
$ edit/compile/test $ edit/compile/test
$ git checkout -- curses/ux_audio_oss.c <2> $ git restore curses/ux_audio_oss.c <2>
$ git add curses/ux_audio_alsa.c <3> $ git add curses/ux_audio_alsa.c <3>
$ edit/compile/test $ edit/compile/test
$ git diff HEAD <4> $ git diff HEAD <4>
@ -90,7 +89,7 @@ $ git commit -a -s <5>
$ edit/compile/test $ edit/compile/test
$ git diff HEAD^ <6> $ git diff HEAD^ <6>
$ git commit -a --amend <7> $ git commit -a --amend <7>
$ git checkout master <8> $ git switch master <8>
$ git merge alsa-audio <9> $ git merge alsa-audio <9>
$ git log --since='3 days ago' <10> $ git log --since='3 days ago' <10>
$ git log v2.43.. curses/ <11> $ git log v2.43.. curses/ <11>
@ -148,11 +147,11 @@ Clone the upstream and work on it. Feed changes to upstream.::
------------ ------------
$ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6 $ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6
$ cd my2.6 $ cd my2.6
$ git checkout -b mine master <1> $ git switch -c mine master <1>
$ edit/compile/test; git commit -a -s <2> $ edit/compile/test; git commit -a -s <2>
$ git format-patch master <3> $ git format-patch master <3>
$ git send-email --to="person <email@example.com>" 00*.patch <4> $ git send-email --to="person <email@example.com>" 00*.patch <4>
$ git checkout master <5> $ git switch master <5>
$ git pull <6> $ git pull <6>
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <7> $ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <7>
$ git ls-remote --heads http://git.kernel.org/.../jgarzik/libata-dev.git <8> $ git ls-remote --heads http://git.kernel.org/.../jgarzik/libata-dev.git <8>
@ -194,7 +193,7 @@ satellite$ edit/compile/test/commit
satellite$ git push origin <4> satellite$ git push origin <4>
mothership$ cd frotz mothership$ cd frotz
mothership$ git checkout master mothership$ git switch master
mothership$ git merge satellite/master <5> mothership$ git merge satellite/master <5>
------------ ------------
+ +
@ -216,7 +215,7 @@ machine into the master branch.
Branch off of a specific tag.:: Branch off of a specific tag.::
+ +
------------ ------------
$ git checkout -b private2.6.14 v2.6.14 <1> $ git switch -c private2.6.14 v2.6.14 <1>
$ edit/compile/test; git commit -a $ edit/compile/test; git commit -a
$ git checkout master $ git checkout master
$ git cherry-pick v2.6.14..private2.6.14 <2> $ git cherry-pick v2.6.14..private2.6.14 <2>
@ -274,14 +273,14 @@ $ mailx <3>
& s 2 3 4 5 ./+to-apply & s 2 3 4 5 ./+to-apply
& s 7 8 ./+hold-linus & s 7 8 ./+hold-linus
& q & q
$ git checkout -b topic/one master $ git switch -c topic/one master
$ git am -3 -i -s ./+to-apply <4> $ git am -3 -i -s ./+to-apply <4>
$ compile/test $ compile/test
$ git checkout -b hold/linus && git am -3 -i -s ./+hold-linus <5> $ git switch -c hold/linus && git am -3 -i -s ./+hold-linus <5>
$ git checkout topic/one && git rebase master <6> $ git switch topic/one && git rebase master <6>
$ git checkout pu && git reset --hard next <7> $ git switch -C pu next <7>
$ git merge topic/one topic/two && git merge hold/linus <8> $ git merge topic/one topic/two && git merge hold/linus <8>
$ git checkout maint $ git switch maint
$ git cherry-pick master~4 <9> $ git cherry-pick master~4 <9>
$ compile/test $ compile/test
$ git tag -s -m "GIT 0.99.9x" v0.99.9x <10> $ git tag -s -m "GIT 0.99.9x" v0.99.9x <10>

View File

@ -165,12 +165,13 @@ rebased, and is not set when rebasing the current branch.
post-checkout post-checkout
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
This hook is invoked when a linkgit:git-checkout[1] is run after having updated the This hook is invoked when a linkgit:git-checkout[1] or
linkgit:git-switch[1] is run after having updated the
worktree. The hook is given three parameters: the ref of the previous HEAD, worktree. The hook is given three parameters: the ref of the previous HEAD,
the ref of the new HEAD (which may or may not have changed), and a flag the ref of the new HEAD (which may or may not have changed), and a flag
indicating whether the checkout was a branch checkout (changing branches, indicating whether the checkout was a branch checkout (changing branches,
flag=1) or a file checkout (retrieving a file from the index, flag=0). flag=1) or a file checkout (retrieving a file from the index, flag=0).
This hook cannot affect the outcome of `git checkout`. This hook cannot affect the outcome of `git switch` or `git checkout`.
It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is
used. The first parameter given to the hook is the null-ref, the second the used. The first parameter given to the hook is the null-ref, the second the
@ -406,7 +407,8 @@ exit with a zero status.
For example, the hook can simply run `git read-tree -u -m HEAD "$1"` For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
in order to emulate `git fetch` that is run in the reverse direction in order to emulate `git fetch` that is run in the reverse direction
with `git push`, as the two-tree form of `git read-tree -u -m` is with `git push`, as the two-tree form of `git read-tree -u -m` is
essentially the same as `git checkout` that switches branches while essentially the same as `git switch` or `git checkout`
that switches branches while
keeping the local changes in the working tree that do not interfere keeping the local changes in the working tree that do not interfere
with the difference between the branches. with the difference between the branches.

View File

@ -89,28 +89,28 @@ PATTERN FORMAT
Put a backslash ("`\`") in front of the first "`!`" for patterns Put a backslash ("`\`") in front of the first "`!`" for patterns
that begin with a literal "`!`", for example, "`\!important!.txt`". that begin with a literal "`!`", for example, "`\!important!.txt`".
- If the pattern ends with a slash, it is removed for the - The slash '/' is used as the directory separator. Separators may
purpose of the following description, but it would only find occur at the beginning, middle or end of the `.gitignore` search pattern.
a match with a directory. In other words, `foo/` will match a
directory `foo` and paths underneath it, but will not match a
regular file or a symbolic link `foo` (this is consistent
with the way how pathspec works in general in Git).
- If the pattern does not contain a slash '/', Git treats it as - If there is a separator at the beginning or middle (or both) of the
a shell glob pattern and checks for a match against the pattern, then the pattern is relative to the directory level of the
pathname relative to the location of the `.gitignore` file particular `.gitignore` file itself. Otherwise the pattern may also
(relative to the toplevel of the work tree if not from a match at any level below the `.gitignore` level.
`.gitignore` file).
- Otherwise, Git treats the pattern as a shell glob: "`*`" matches - If there is a separator at the end of the pattern then the pattern
anything except "`/`", "`?`" matches any one character except "`/`" will only match directories, otherwise the pattern can match both
and "`[]`" matches one character in a selected range. See files and directories.
fnmatch(3) and the FNM_PATHNAME flag for a more detailed
description.
- A leading slash matches the beginning of the pathname. - For example, a pattern `doc/frotz/` matches `doc/frotz` directory,
For example, "/{asterisk}.c" matches "cat-file.c" but not but not `a/doc/frotz` directory; however `frotz/` matches `frotz`
"mozilla-sha1/sha1.c". and `a/frotz` that is a directory (all paths are relative from
the `.gitignore` file).
- An asterisk "`*`" matches anything except a slash.
The character "`?`" matches any one character except "`/`".
The range notation, e.g. `[a-zA-Z]`, can be used to match
one of the characters in a range. See fnmatch(3) and the
FNM_PATHNAME flag for a more detailed description.
Two consecutive asterisks ("`**`") in patterns matched against Two consecutive asterisks ("`**`") in patterns matched against
full pathname may have special meaning: full pathname may have special meaning:
@ -152,6 +152,28 @@ To stop tracking a file that is currently tracked, use
EXAMPLES EXAMPLES
-------- --------
- The pattern `hello.*` matches any file or folder
whose name begins with `hello`. If one wants to restrict
this only to the directory and not in its subdirectories,
one can prepend the pattern with a slash, i.e. `/hello.*`;
the pattern now matches `hello.txt`, `hello.c` but not
`a/hello.java`.
- The pattern `foo/` will match a directory `foo` and
paths underneath it, but will not match a regular file
or a symbolic link `foo` (this is consistent with the
way how pathspec works in general in Git)
- The pattern `doc/frotz` and `/doc/frotz` have the same effect
in any `.gitignore` file. In other words, a leading slash
is not relevant if there is already a middle slash in
the pattern.
- The pattern "foo/*", matches "foo/test.json"
(a regular file), "foo/bar" (a directory), but it does not match
"foo/bar/hello.c" (a regular file), as the asterisk in the
pattern does not match "bar/hello.c" which has a slash in it.
-------------------------------------------------------------- --------------------------------------------------------------
$ git status $ git status
[...] [...]

View File

@ -370,13 +370,13 @@ situation:
$ git status $ git status
On branch master On branch master
Changes to be committed: Changes to be committed:
(use "git reset HEAD <file>..." to unstage) (use "git restore --staged <file>..." to unstage)
new file: closing.txt new file: closing.txt
Changes not staged for commit: Changes not staged for commit:
(use "git add <file>..." to update what will be committed) (use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory) (use "git restore <file>..." to discard changes in working directory)
modified: file.txt modified: file.txt

View File

@ -110,7 +110,7 @@ $ git status
On branch master On branch master
Changes to be committed: Changes to be committed:
Your branch is up to date with 'origin/master'. Your branch is up to date with 'origin/master'.
(use "git reset HEAD <file>..." to unstage) (use "git restore --staged <file>..." to unstage)
modified: file1 modified: file1
modified: file2 modified: file2
@ -207,7 +207,7 @@ automatically. The asterisk marks the branch you are currently on;
type type
------------------------------------------------ ------------------------------------------------
$ git checkout experimental $ git switch experimental
------------------------------------------------ ------------------------------------------------
to switch to the experimental branch. Now edit a file, commit the to switch to the experimental branch. Now edit a file, commit the
@ -216,7 +216,7 @@ change, and switch back to the master branch:
------------------------------------------------ ------------------------------------------------
(edit file) (edit file)
$ git commit -a $ git commit -a
$ git checkout master $ git switch master
------------------------------------------------ ------------------------------------------------
Check that the change you made is no longer visible, since it was Check that the change you made is no longer visible, since it was

View File

@ -28,8 +28,7 @@ Gitweb provides a web interface to Git repositories. Its features include:
revisions one at a time, viewing the history of the repository. revisions one at a time, viewing the history of the repository.
* Finding commits which commit messages matches given search term. * Finding commits which commit messages matches given search term.
See http://git.kernel.org/?p=git/git.git;a=tree;f=gitweb[] or See http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
browsed using gitweb itself. browsed using gitweb itself.

View File

@ -301,8 +301,7 @@ topics on 'next':
.Rewind and rebuild next .Rewind and rebuild next
[caption="Recipe: "] [caption="Recipe: "]
===================================== =====================================
* `git checkout next` * `git switch -C next master`
* `git reset --hard master`
* `git merge ai/topic_in_next1` * `git merge ai/topic_in_next1`
* `git merge ai/topic_in_next2` * `git merge ai/topic_in_next2`
* ... * ...

View File

@ -102,6 +102,8 @@ merge.
+ +
With --no-squash perform the merge and commit the result. This With --no-squash perform the merge and commit the result. This
option can be used to override --squash. option can be used to override --squash.
+
With --squash, --commit is not allowed, and will fail.
-s <strategy>:: -s <strategy>::
--strategy=<strategy>:: --strategy=<strategy>::

View File

@ -182,6 +182,14 @@ explicitly.
Pretend as if all objects mentioned by reflogs are listed on the Pretend as if all objects mentioned by reflogs are listed on the
command line as `<commit>`. command line as `<commit>`.
--alternate-refs::
Pretend as if all objects mentioned as ref tips of alternate
repositories were listed on the command line. An alternate
repository is any repository whose object directory is specified
in `objects/info/alternates`. The set of included objects may
be modified by `core.alternateRefsCommand`, etc. See
linkgit:git-config[1].
--single-worktree:: --single-worktree::
By default, all working trees will be examined by the By default, all working trees will be examined by the
following options when there are more than one (see following options when there are more than one (see
@ -708,6 +716,16 @@ ifdef::git-rev-list[]
Only useful with `--objects`; print the object IDs that are not Only useful with `--objects`; print the object IDs that are not
in packs. in packs.
--object-names::
Only useful with `--objects`; print the names of the object IDs
that are found. This is the default behavior.
--no-object-names::
Only useful with `--objects`; does not print the names of the object
IDs that are found. This inverts `--object-names`. This flag allows
the output to be more easily parsed by commands such as
linkgit:git-cat-file[1].
--filter=<filter-spec>:: --filter=<filter-spec>::
Only useful with one of the `--objects*`; omits objects (usually Only useful with one of the `--objects*`; omits objects (usually
blobs) from the list of printed objects. The '<filter-spec>' blobs) from the list of printed objects. The '<filter-spec>'

View File

@ -115,7 +115,7 @@ Here's an example to make it more clear:
------------------------------ ------------------------------
$ git config push.default current $ git config push.default current
$ git config remote.pushdefault myfork $ git config remote.pushdefault myfork
$ git checkout -b mybranch origin/master $ git switch -c mybranch origin/master
$ git rev-parse --symbolic-full-name @{upstream} $ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master refs/remotes/origin/master

View File

@ -3,6 +3,10 @@
`.git/sequencer`. Can be used to continue after resolving `.git/sequencer`. Can be used to continue after resolving
conflicts in a failed cherry-pick or revert. conflicts in a failed cherry-pick or revert.
--skip::
Skip the current commit and continue with the rest of the
sequence.
--quit:: --quit::
Forget about the current operation in progress. Can be used Forget about the current operation in progress. Can be used
to clear the sequencer state after a failed cherry-pick or to clear the sequencer state after a failed cherry-pick or

View File

@ -35,7 +35,7 @@ Format details are given in a later section.
=== The Normal Format Target === The Normal Format Target
The normal format target is a tradition printf format and similar The normal format target is a tradition printf format and similar
to GIT_TRACE format. This format is enabled with the `GIT_TR` to GIT_TRACE format. This format is enabled with the `GIT_TRACE2`
environment variable or the `trace2.normalTarget` system or global environment variable or the `trace2.normalTarget` system or global
config setting. config setting.
@ -668,7 +668,7 @@ completed.)
"event":"signal", "event":"signal",
... ...
"t_abs":0.001227, # elapsed time in seconds "t_abs":0.001227, # elapsed time in seconds
"signal":13 # SIGTERM, SIGINT, etc. "signo":13 # SIGTERM, SIGINT, etc.
} }
------------ ------------

View File

@ -44,8 +44,9 @@ HEADER:
1-byte number (C) of "chunks" 1-byte number (C) of "chunks"
1-byte (reserved for later use) 1-byte number (B) of base commit-graphs
Current clients should ignore this value. We infer the length (H*B) of the Base Graphs chunk
from this value.
CHUNK LOOKUP: CHUNK LOOKUP:
@ -92,6 +93,12 @@ CHUNK DATA:
positions for the parents until reaching a value with the most-significant positions for the parents until reaching a value with the most-significant
bit on. The other bits correspond to the position of the last parent. bit on. The other bits correspond to the position of the last parent.
Base Graphs List (ID: {'B', 'A', 'S', 'E'}) [Optional]
This list of H-byte hashes describe a set of B commit-graph files that
form a commit-graph chain. The graph position for the ith commit in this
file's OID Lookup chunk is equal to i plus the number of commits in all
base graphs. If B is non-zero, this chunk must exist.
TRAILER: TRAILER:
H-byte HASH-checksum of all of the above. H-byte HASH-checksum of all of the above.

View File

@ -127,22 +127,196 @@ Design Details
helpful for these clones, anyway. The commit-graph will not be read or helpful for these clones, anyway. The commit-graph will not be read or
written when shallow commits are present. written when shallow commits are present.
Future Work Commit Graphs Chains
----------- --------------------
- After computing and storing generation numbers, we must make graph Typically, repos grow with near-constant velocity (commits per day). Over time,
walks aware of generation numbers to gain the performance benefits they the number of commits added by a fetch operation is much smaller than the
enable. This will mostly be accomplished by swapping a commit-date-ordered number of commits in the full history. By creating a "chain" of commit-graphs,
priority queue with one ordered by generation number. The following we enable fast writes of new commit data without rewriting the entire commit
operations are important candidates: history -- at least, most of the time.
- 'log --topo-order' ## File Layout
- 'tag --merged'
- A server could provide a commit-graph file as part of the network protocol A commit-graph chain uses multiple files, and we use a fixed naming convention
to avoid extra calculations by clients. This feature is only of benefit if to organize these files. Each commit-graph file has a name
the user is willing to trust the file, because verifying the file is correct `$OBJDIR/info/commit-graphs/graph-{hash}.graph` where `{hash}` is the hex-
is as hard as computing it from scratch. valued hash stored in the footer of that file (which is a hash of the file's
contents before that hash). For a chain of commit-graph files, a plain-text
file at `$OBJDIR/info/commit-graphs/commit-graph-chain` contains the
hashes for the files in order from "lowest" to "highest".
For example, if the `commit-graph-chain` file contains the lines
```
{hash0}
{hash1}
{hash2}
```
then the commit-graph chain looks like the following diagram:
+-----------------------+
| graph-{hash2}.graph |
+-----------------------+
|
+-----------------------+
| |
| graph-{hash1}.graph |
| |
+-----------------------+
|
+-----------------------+
| |
| |
| |
| graph-{hash0}.graph |
| |
| |
| |
+-----------------------+
Let X0 be the number of commits in `graph-{hash0}.graph`, X1 be the number of
commits in `graph-{hash1}.graph`, and X2 be the number of commits in
`graph-{hash2}.graph`. If a commit appears in position i in `graph-{hash2}.graph`,
then we interpret this as being the commit in position (X0 + X1 + i), and that
will be used as its "graph position". The commits in `graph-{hash2}.graph` use these
positions to refer to their parents, which may be in `graph-{hash1}.graph` or
`graph-{hash0}.graph`. We can navigate to an arbitrary commit in position j by checking
its containment in the intervals [0, X0), [X0, X0 + X1), [X0 + X1, X0 + X1 +
X2).
Each commit-graph file (except the base, `graph-{hash0}.graph`) contains data
specifying the hashes of all files in the lower layers. In the above example,
`graph-{hash1}.graph` contains `{hash0}` while `graph-{hash2}.graph` contains
`{hash0}` and `{hash1}`.
## Merging commit-graph files
If we only added a new commit-graph file on every write, we would run into a
linear search problem through many commit-graph files. Instead, we use a merge
strategy to decide when the stack should collapse some number of levels.
The diagram below shows such a collapse. As a set of new commits are added, it
is determined by the merge strategy that the files should collapse to
`graph-{hash1}`. Thus, the new commits, the commits in `graph-{hash2}` and
the commits in `graph-{hash1}` should be combined into a new `graph-{hash3}`
file.
+---------------------+
| |
| (new commits) |
| |
+---------------------+
| |
+-----------------------+ +---------------------+
| graph-{hash2} |->| |
+-----------------------+ +---------------------+
| | |
+-----------------------+ +---------------------+
| | | |
| graph-{hash1} |->| |
| | | |
+-----------------------+ +---------------------+
| tmp_graphXXX
+-----------------------+
| |
| |
| |
| graph-{hash0} |
| |
| |
| |
+-----------------------+
During this process, the commits to write are combined, sorted and we write the
contents to a temporary file, all while holding a `commit-graph-chain.lock`
lock-file. When the file is flushed, we rename it to `graph-{hash3}`
according to the computed `{hash3}`. Finally, we write the new chain data to
`commit-graph-chain.lock`:
```
{hash3}
{hash0}
```
We then close the lock-file.
## Merge Strategy
When writing a set of commits that do not exist in the commit-graph stack of
height N, we default to creating a new file at level N + 1. We then decide to
merge with the Nth level if one of two conditions hold:
1. `--size-multiple=<X>` is specified or X = 2, and the number of commits in
level N is less than X times the number of commits in level N + 1.
2. `--max-commits=<C>` is specified with non-zero C and the number of commits
in level N + 1 is more than C commits.
This decision cascades down the levels: when we merge a level we create a new
set of commits that then compares to the next level.
The first condition bounds the number of levels to be logarithmic in the total
number of commits. The second condition bounds the total number of commits in
a `graph-{hashN}` file and not in the `commit-graph` file, preventing
significant performance issues when the stack merges and another process only
partially reads the previous stack.
The merge strategy values (2 for the size multiple, 64,000 for the maximum
number of commits) could be extracted into config settings for full
flexibility.
## Deleting graph-{hash} files
After a new tip file is written, some `graph-{hash}` files may no longer
be part of a chain. It is important to remove these files from disk, eventually.
The main reason to delay removal is that another process could read the
`commit-graph-chain` file before it is rewritten, but then look for the
`graph-{hash}` files after they are deleted.
To allow holding old split commit-graphs for a while after they are unreferenced,
we update the modified times of the files when they become unreferenced. Then,
we scan the `$OBJDIR/info/commit-graphs/` directory for `graph-{hash}`
files whose modified times are older than a given expiry window. This window
defaults to zero, but can be changed using command-line arguments or a config
setting.
## Chains across multiple object directories
In a repo with alternates, we look for the `commit-graph-chain` file starting
in the local object directory and then in each alternate. The first file that
exists defines our chain. As we look for the `graph-{hash}` files for
each `{hash}` in the chain file, we follow the same pattern for the host
directories.
This allows commit-graphs to be split across multiple forks in a fork network.
The typical case is a large "base" repo with many smaller forks.
As the base repo advances, it will likely update and merge its commit-graph
chain more frequently than the forks. If a fork updates their commit-graph after
the base repo, then it should "reparent" the commit-graph chain onto the new
chain in the base repo. When reading each `graph-{hash}` file, we track
the object directory containing it. During a write of a new commit-graph file,
we check for any changes in the source object directory and read the
`commit-graph-chain` file for that source and create a new file based on those
files. During this "reparent" operation, we necessarily need to collapse all
levels in the fork, as all of the files are invalid against the new base file.
It is crucial to be careful when cleaning up "unreferenced" `graph-{hash}.graph`
files in this scenario. It falls to the user to define the proper settings for
their custom environment:
1. When merging levels in the base repo, the unreferenced files may still be
referenced by chains from fork repos.
2. The expiry time should be set to a length of time such that every fork has
time to recompute their commit-graph chain to "reparent" onto the new base
file(s).
3. If the commit-graph chain is updated in the base, the fork will not have
access to the new chain until its chain is updated to reference those files.
(This may change in the future [5].)
Related Links Related Links
------------- -------------
@ -170,3 +344,7 @@ Related Links
[4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u [4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u
A patch to remove the ahead-behind calculation from 'status'. A patch to remove the ahead-behind calculation from 'status'.
[5] https://public-inbox.org/git/f27db281-abad-5043-6d71-cbb083b1c877@gmail.com/
A discussion of a "two-dimensional graph position" that can allow reading
multiple commit-graph chains at the same time.

View File

@ -122,10 +122,10 @@ Tags are expected to always point at the same version of a project,
while heads are expected to advance as development progresses. while heads are expected to advance as development progresses.
Create a new branch head pointing to one of these versions and check it Create a new branch head pointing to one of these versions and check it
out using linkgit:git-checkout[1]: out using linkgit:git-switch[1]:
------------------------------------------------ ------------------------------------------------
$ git checkout -b new v2.6.13 $ git switch -c new v2.6.13
------------------------------------------------ ------------------------------------------------
The working directory then reflects the contents that the project had The working directory then reflects the contents that the project had
@ -282,10 +282,10 @@ a summary of the commands:
this command will fail with a warning. this command will fail with a warning.
`git branch -D <branch>`:: `git branch -D <branch>`::
delete the branch `<branch>` irrespective of its merged status. delete the branch `<branch>` irrespective of its merged status.
`git checkout <branch>`:: `git switch <branch>`::
make the current branch `<branch>`, updating the working make the current branch `<branch>`, updating the working
directory to reflect the version referenced by `<branch>`. directory to reflect the version referenced by `<branch>`.
`git checkout -b <new> <start-point>`:: `git switch -c <new> <start-point>`::
create a new branch `<new>` referencing `<start-point>`, and create a new branch `<new>` referencing `<start-point>`, and
check it out. check it out.
@ -302,22 +302,22 @@ ref: refs/heads/master
Examining an old version without creating a new branch Examining an old version without creating a new branch
------------------------------------------------------ ------------------------------------------------------
The `git checkout` command normally expects a branch head, but will also The `git switch` command normally expects a branch head, but will also
accept an arbitrary commit; for example, you can check out the commit accept an arbitrary commit when invoked with --detach; for example,
referenced by a tag: you can check out the commit referenced by a tag:
------------------------------------------------ ------------------------------------------------
$ git checkout v2.6.17 $ git switch --detach v2.6.17
Note: checking out 'v2.6.17'. Note: checking out 'v2.6.17'.
You are in 'detached HEAD' state. You can look around, make experimental You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout. state without impacting any branches by performing another switch.
If you want to create a new branch to retain commits you create, you may If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example: do so (now or later) by using -c with the switch command again. Example:
git checkout -b new_branch_name git switch -c new_branch_name
HEAD is now at 427abfa Linux v2.6.17 HEAD is now at 427abfa Linux v2.6.17
------------------------------------------------ ------------------------------------------------
@ -373,7 +373,7 @@ You might want to build on one of these remote-tracking branches
on a branch of your own, just as you would for a tag: on a branch of your own, just as you would for a tag:
------------------------------------------------ ------------------------------------------------
$ git checkout -b my-todo-copy origin/todo $ git switch -c my-todo-copy origin/todo
------------------------------------------------ ------------------------------------------------
You can also check out `origin/todo` directly to examine it or You can also check out `origin/todo` directly to examine it or
@ -1408,7 +1408,7 @@ If you get stuck and decide to just give up and throw the whole mess
away, you can always return to the pre-merge state with away, you can always return to the pre-merge state with
------------------------------------------------- -------------------------------------------------
$ git reset --hard HEAD $ git merge --abort
------------------------------------------------- -------------------------------------------------
Or, if you've already committed the merge that you want to throw away, Or, if you've already committed the merge that you want to throw away,
@ -1446,7 +1446,7 @@ mistake, you can return the entire working tree to the last committed
state with state with
------------------------------------------------- -------------------------------------------------
$ git reset --hard HEAD $ git restore --staged --worktree :/
------------------------------------------------- -------------------------------------------------
If you make a commit that you later wish you hadn't, there are two If you make a commit that you later wish you hadn't, there are two
@ -1523,12 +1523,10 @@ Checking out an old version of a file
In the process of undoing a previous bad change, you may find it In the process of undoing a previous bad change, you may find it
useful to check out an older version of a particular file using useful to check out an older version of a particular file using
linkgit:git-checkout[1]. We've used `git checkout` before to switch linkgit:git-restore[1]. The command
branches, but it has quite different behavior if it is given a path
name: the command
------------------------------------------------- -------------------------------------------------
$ git checkout HEAD^ path/to/file $ git restore --source=HEAD^ path/to/file
------------------------------------------------- -------------------------------------------------
replaces path/to/file by the contents it had in the commit HEAD^, and replaces path/to/file by the contents it had in the commit HEAD^, and
@ -2211,8 +2209,8 @@ $ git branch --track release origin/master
These can be easily kept up to date using linkgit:git-pull[1]. These can be easily kept up to date using linkgit:git-pull[1].
------------------------------------------------- -------------------------------------------------
$ git checkout test && git pull $ git switch test && git pull
$ git checkout release && git pull $ git switch release && git pull
------------------------------------------------- -------------------------------------------------
Important note! If you have any local changes in these branches, then Important note! If you have any local changes in these branches, then
@ -2264,7 +2262,7 @@ tested changes
2) help future bug hunters that use `git bisect` to find problems 2) help future bug hunters that use `git bisect` to find problems
------------------------------------------------- -------------------------------------------------
$ git checkout -b speed-up-spinlocks v2.6.35 $ git switch -c speed-up-spinlocks v2.6.35
------------------------------------------------- -------------------------------------------------
Now you apply the patch(es), run some tests, and commit the change(s). If Now you apply the patch(es), run some tests, and commit the change(s). If
@ -2279,7 +2277,7 @@ When you are happy with the state of this change, you can merge it into the
"test" branch in preparation to make it public: "test" branch in preparation to make it public:
------------------------------------------------- -------------------------------------------------
$ git checkout test && git merge speed-up-spinlocks $ git switch test && git merge speed-up-spinlocks
------------------------------------------------- -------------------------------------------------
It is unlikely that you would have any conflicts here ... but you might if you It is unlikely that you would have any conflicts here ... but you might if you
@ -2291,7 +2289,7 @@ see the value of keeping each patch (or patch series) in its own branch. It
means that the patches can be moved into the `release` tree in any order. means that the patches can be moved into the `release` tree in any order.
------------------------------------------------- -------------------------------------------------
$ git checkout release && git merge speed-up-spinlocks $ git switch release && git merge speed-up-spinlocks
------------------------------------------------- -------------------------------------------------
After a while, you will have a number of branches, and despite the After a while, you will have a number of branches, and despite the
@ -2512,7 +2510,7 @@ Suppose that you create a branch `mywork` on a remote-tracking branch
`origin`, and create some commits on top of it: `origin`, and create some commits on top of it:
------------------------------------------------- -------------------------------------------------
$ git checkout -b mywork origin $ git switch -c mywork origin
$ vi file.txt $ vi file.txt
$ git commit $ git commit
$ vi otherfile.txt $ vi otherfile.txt
@ -2552,7 +2550,7 @@ commits without any merges, you may instead choose to use
linkgit:git-rebase[1]: linkgit:git-rebase[1]:
------------------------------------------------- -------------------------------------------------
$ git checkout mywork $ git switch mywork
$ git rebase origin $ git rebase origin
------------------------------------------------- -------------------------------------------------
@ -3668,13 +3666,13 @@ change within the submodule, and then update the superproject to reference the
new commit: new commit:
------------------------------------------------- -------------------------------------------------
$ git checkout master $ git switch master
------------------------------------------------- -------------------------------------------------
or or
------------------------------------------------- -------------------------------------------------
$ git checkout -b fix-up $ git switch -c fix-up
------------------------------------------------- -------------------------------------------------
then then
@ -3800,8 +3798,8 @@ use linkgit:git-tag[1] for both.
The Workflow The Workflow
------------ ------------
High-level operations such as linkgit:git-commit[1], High-level operations such as linkgit:git-commit[1] and
linkgit:git-checkout[1] and linkgit:git-reset[1] work by moving data linkgit:git-restore[1] work by moving data
between the working tree, the index, and the object database. Git between the working tree, the index, and the object database. Git
provides low-level operations which perform each of these steps provides low-level operations which perform each of these steps
individually. individually.
@ -4194,7 +4192,7 @@ start.
A good place to start is with the contents of the initial commit, with: A good place to start is with the contents of the initial commit, with:
---------------------------------------------------- ----------------------------------------------------
$ git checkout e83c5163 $ git switch --detach e83c5163
---------------------------------------------------- ----------------------------------------------------
The initial revision lays the foundation for almost everything Git has The initial revision lays the foundation for almost everything Git has
@ -4438,7 +4436,7 @@ Managing branches
----------------------------------------------- -----------------------------------------------
$ git branch # list all local branches in this repo $ git branch # list all local branches in this repo
$ git checkout test # switch working directory to branch "test" $ git switch test # switch working directory to branch "test"
$ git branch new # create branch "new" starting at current HEAD $ git branch new # create branch "new" starting at current HEAD
$ git branch -d new # delete branch "new" $ git branch -d new # delete branch "new"
----------------------------------------------- -----------------------------------------------
@ -4456,7 +4454,7 @@ $ git branch new test~10 # ten commits before tip of branch "test"
Create and switch to a new branch at the same time: Create and switch to a new branch at the same time:
----------------------------------------------- -----------------------------------------------
$ git checkout -b new v2.6.15 $ git switch -c new v2.6.15
----------------------------------------------- -----------------------------------------------
Update and examine branches from the repository you cloned from: Update and examine branches from the repository you cloned from:
@ -4467,7 +4465,7 @@ $ git branch -r # list
origin/master origin/master
origin/next origin/next
... ...
$ git checkout -b masterwork origin/master $ git switch -c masterwork origin/master
----------------------------------------------- -----------------------------------------------
Fetch a branch from a different repository, and give it a new Fetch a branch from a different repository, and give it a new

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
GVF=GIT-VERSION-FILE GVF=GIT-VERSION-FILE
DEF_VER=v2.22.0 DEF_VER=v2.23.0-rc0
LF=' LF='
' '

View File

@ -265,10 +265,6 @@ all::
# #
# Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound.
# #
# Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib"
# that tells runtime paths to dynamic libraries;
# "-Wl,-rpath=/path/lib" is used instead.
#
# Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback,
# as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) # as the compiler can crash (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299)
# #
@ -624,8 +620,6 @@ SCRIPT_SH += git-web--browse.sh
SCRIPT_LIB += git-mergetool--lib SCRIPT_LIB += git-mergetool--lib
SCRIPT_LIB += git-parse-remote SCRIPT_LIB += git-parse-remote
SCRIPT_LIB += git-rebase--am
SCRIPT_LIB += git-rebase--common
SCRIPT_LIB += git-rebase--preserve-merges SCRIPT_LIB += git-rebase--preserve-merges
SCRIPT_LIB += git-sh-setup SCRIPT_LIB += git-sh-setup
SCRIPT_LIB += git-sh-i18n SCRIPT_LIB += git-sh-i18n
@ -710,6 +704,7 @@ TEST_BUILTINS_OBJS += test-config.o
TEST_BUILTINS_OBJS += test-ctype.o TEST_BUILTINS_OBJS += test-ctype.o
TEST_BUILTINS_OBJS += test-date.o TEST_BUILTINS_OBJS += test-date.o
TEST_BUILTINS_OBJS += test-delta.o TEST_BUILTINS_OBJS += test-delta.o
TEST_BUILTINS_OBJS += test-dir-iterator.o
TEST_BUILTINS_OBJS += test-drop-caches.o TEST_BUILTINS_OBJS += test-drop-caches.o
TEST_BUILTINS_OBJS += test-dump-cache-tree.o TEST_BUILTINS_OBJS += test-dump-cache-tree.o
TEST_BUILTINS_OBJS += test-dump-fsmonitor.o TEST_BUILTINS_OBJS += test-dump-fsmonitor.o
@ -727,6 +722,7 @@ TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
TEST_BUILTINS_OBJS += test-match-trees.o TEST_BUILTINS_OBJS += test-match-trees.o
TEST_BUILTINS_OBJS += test-mergesort.o TEST_BUILTINS_OBJS += test-mergesort.o
TEST_BUILTINS_OBJS += test-mktemp.o TEST_BUILTINS_OBJS += test-mktemp.o
TEST_BUILTINS_OBJS += test-oidmap.o
TEST_BUILTINS_OBJS += test-online-cpus.o TEST_BUILTINS_OBJS += test-online-cpus.o
TEST_BUILTINS_OBJS += test-parse-options.o TEST_BUILTINS_OBJS += test-parse-options.o
TEST_BUILTINS_OBJS += test-path-utils.o TEST_BUILTINS_OBJS += test-path-utils.o
@ -777,9 +773,11 @@ BUILT_INS += git-format-patch$X
BUILT_INS += git-fsck-objects$X BUILT_INS += git-fsck-objects$X
BUILT_INS += git-init$X BUILT_INS += git-init$X
BUILT_INS += git-merge-subtree$X BUILT_INS += git-merge-subtree$X
BUILT_INS += git-restore$X
BUILT_INS += git-show$X BUILT_INS += git-show$X
BUILT_INS += git-stage$X BUILT_INS += git-stage$X
BUILT_INS += git-status$X BUILT_INS += git-status$X
BUILT_INS += git-switch$X
BUILT_INS += git-whatchanged$X BUILT_INS += git-whatchanged$X
# what 'all' will build and 'install' will install in gitexecdir, # what 'all' will build and 'install' will install in gitexecdir,
@ -1065,6 +1063,7 @@ BUILTIN_OBJS += builtin/diff-index.o
BUILTIN_OBJS += builtin/diff-tree.o BUILTIN_OBJS += builtin/diff-tree.o
BUILTIN_OBJS += builtin/diff.o BUILTIN_OBJS += builtin/diff.o
BUILTIN_OBJS += builtin/difftool.o BUILTIN_OBJS += builtin/difftool.o
BUILTIN_OBJS += builtin/env--helper.o
BUILTIN_OBJS += builtin/fast-export.o BUILTIN_OBJS += builtin/fast-export.o
BUILTIN_OBJS += builtin/fetch-pack.o BUILTIN_OBJS += builtin/fetch-pack.o
BUILTIN_OBJS += builtin/fetch.o BUILTIN_OBJS += builtin/fetch.o
@ -1160,6 +1159,7 @@ endif
# which'll override these defaults. # which'll override these defaults.
CFLAGS = -g -O2 -Wall CFLAGS = -g -O2 -Wall
LDFLAGS = LDFLAGS =
CC_LD_DYNPATH = -Wl,-rpath,
BASIC_CFLAGS = -I. BASIC_CFLAGS = -I.
BASIC_LDFLAGS = BASIC_LDFLAGS =
@ -1240,7 +1240,7 @@ endif
ifdef SANE_TOOL_PATH ifdef SANE_TOOL_PATH
SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH)) SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH))
BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix $(SANE_TOOL_PATH_SQ)|' BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"|'
PATH := $(SANE_TOOL_PATH):${PATH} PATH := $(SANE_TOOL_PATH):${PATH}
else else
BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d' BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d'
@ -1290,16 +1290,6 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS = PTHREAD_LIBS =
endif endif
ifndef CC_LD_DYNPATH
ifdef NO_R_TO_GCC_LINKER
# Some gcc does not accept and pass -R to the linker to specify
# the runtime dynamic library path.
CC_LD_DYNPATH = -Wl,-rpath,
else
CC_LD_DYNPATH = -R
endif
endif
ifdef NO_LIBGEN_H ifdef NO_LIBGEN_H
COMPAT_CFLAGS += -DNO_LIBGEN_H COMPAT_CFLAGS += -DNO_LIBGEN_H
COMPAT_OBJS += compat/basename.o COMPAT_OBJS += compat/basename.o
@ -2873,6 +2863,33 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' $(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
ifdef MSVC
# We DO NOT install the individual foo.o.pdb files because they
# have already been rolled up into the exe's pdb file.
# We DO NOT have pdb files for the builtin commands (like git-status.exe)
# because it is just a copy/hardlink of git.exe, rather than a unique binary.
$(INSTALL) git.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-shell.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-upload-pack.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-credential-store.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-daemon.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-fast-import.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-backend.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-fetch.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-push.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-imap-send.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-remote-http.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-remote-testsvn.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-sh-i18n--envsubst.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-show-index.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
ifndef DEBUG
$(INSTALL) $(vcpkg_rel_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(vcpkg_rel_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
else
$(INSTALL) $(vcpkg_dbg_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
endif
endif
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)' $(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
@ -3085,6 +3102,19 @@ endif
$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS
$(RM) GIT-USER-AGENT GIT-PREFIX $(RM) GIT-USER-AGENT GIT-PREFIX
$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS $(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS
ifdef MSVC
$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))
$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.iobj,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.iobj,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(TEST_PROGRAMS))
$(RM) $(patsubst %.exe,%.iobj,$(TEST_PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(TEST_PROGRAMS))
$(RM) compat/vcbuild/MSVC-DEFS-GEN
endif
.PHONY: all install profile-clean cocciclean clean strip .PHONY: all install profile-clean cocciclean clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell

View File

@ -19,7 +19,7 @@ including full documentation and Git related tools.
See [Documentation/gittutorial.txt][] to get started, then see See [Documentation/gittutorial.txt][] to get started, then see
[Documentation/giteveryday.txt][] for a useful minimum set of commands, and [Documentation/giteveryday.txt][] for a useful minimum set of commands, and
Documentation/git-<commandname>.txt for documentation of each command. `Documentation/git-<commandname>.txt` for documentation of each command.
If git has been correctly installed, then the tutorial can also be If git has been correctly installed, then the tutorial can also be
read with `man gittutorial` or `git help tutorial`, and the read with `man gittutorial` or `git help tutorial`, and the
documentation of each command with `man git-<commandname>` or `git help documentation of each command with `man git-<commandname>` or `git help

View File

@ -1 +1 @@
Documentation/RelNotes/2.22.0.txt Documentation/RelNotes/2.23.0.txt

View File

@ -3,6 +3,7 @@
#include "color.h" #include "color.h"
#include "help.h" #include "help.h"
int advice_fetch_show_forced_updates = 1;
int advice_push_update_rejected = 1; int advice_push_update_rejected = 1;
int advice_push_non_ff_current = 1; int advice_push_non_ff_current = 1;
int advice_push_non_ff_matching = 1; int advice_push_non_ff_matching = 1;
@ -12,9 +13,11 @@ int advice_push_needs_force = 1;
int advice_push_unqualified_ref_name = 1; int advice_push_unqualified_ref_name = 1;
int advice_status_hints = 1; int advice_status_hints = 1;
int advice_status_u_option = 1; int advice_status_u_option = 1;
int advice_status_ahead_behind_warning = 1;
int advice_commit_before_merge = 1; int advice_commit_before_merge = 1;
int advice_reset_quiet_warning = 1; int advice_reset_quiet_warning = 1;
int advice_resolve_conflict = 1; int advice_resolve_conflict = 1;
int advice_sequencer_in_use = 1;
int advice_implicit_identity = 1; int advice_implicit_identity = 1;
int advice_detached_head = 1; int advice_detached_head = 1;
int advice_set_upstream_failure = 1; int advice_set_upstream_failure = 1;
@ -59,6 +62,7 @@ static struct {
const char *name; const char *name;
int *preference; int *preference;
} advice_config[] = { } advice_config[] = {
{ "fetchShowForcedUpdates", &advice_fetch_show_forced_updates },
{ "pushUpdateRejected", &advice_push_update_rejected }, { "pushUpdateRejected", &advice_push_update_rejected },
{ "pushNonFFCurrent", &advice_push_non_ff_current }, { "pushNonFFCurrent", &advice_push_non_ff_current },
{ "pushNonFFMatching", &advice_push_non_ff_matching }, { "pushNonFFMatching", &advice_push_non_ff_matching },
@ -68,9 +72,11 @@ static struct {
{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name }, { "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
{ "statusHints", &advice_status_hints }, { "statusHints", &advice_status_hints },
{ "statusUoption", &advice_status_u_option }, { "statusUoption", &advice_status_u_option },
{ "statusAheadBehindWarning", &advice_status_ahead_behind_warning },
{ "commitBeforeMerge", &advice_commit_before_merge }, { "commitBeforeMerge", &advice_commit_before_merge },
{ "resetQuiet", &advice_reset_quiet_warning }, { "resetQuiet", &advice_reset_quiet_warning },
{ "resolveConflict", &advice_resolve_conflict }, { "resolveConflict", &advice_resolve_conflict },
{ "sequencerInUse", &advice_sequencer_in_use },
{ "implicitIdentity", &advice_implicit_identity }, { "implicitIdentity", &advice_implicit_identity },
{ "detachedHead", &advice_detached_head }, { "detachedHead", &advice_detached_head },
{ "setupStreamFailure", &advice_set_upstream_failure }, { "setupStreamFailure", &advice_set_upstream_failure },
@ -193,13 +199,22 @@ void NORETURN die_conclude_merge(void)
void detach_advice(const char *new_name) void detach_advice(const char *new_name)
{ {
const char *fmt = const char *fmt =
_("Note: checking out '%s'.\n\n" _("Note: switching to '%s'.\n"
"\n"
"You are in 'detached HEAD' state. You can look around, make experimental\n" "You are in 'detached HEAD' state. You can look around, make experimental\n"
"changes and commit them, and you can discard any commits you make in this\n" "changes and commit them, and you can discard any commits you make in this\n"
"state without impacting any branches by performing another checkout.\n\n" "state without impacting any branches by switching back to a branch.\n"
"\n"
"If you want to create a new branch to retain commits you create, you may\n" "If you want to create a new branch to retain commits you create, you may\n"
"do so (now or later) by using -b with the checkout command again. Example:\n\n" "do so (now or later) by using -c with the switch command. Example:\n"
" git checkout -b <new-branch-name>\n\n"); "\n"
" git switch -c <new-branch-name>\n"
"\n"
"Or undo this operation with:\n"
"\n"
" git switch -\n"
"\n"
"Turn off this advice by setting config variable advice.detachedHead to false\n\n");
fprintf(stderr, fmt, new_name); fprintf(stderr, fmt, new_name);
} }

View File

@ -3,6 +3,7 @@
#include "git-compat-util.h" #include "git-compat-util.h"
extern int advice_fetch_show_forced_updates;
extern int advice_push_update_rejected; extern int advice_push_update_rejected;
extern int advice_push_non_ff_current; extern int advice_push_non_ff_current;
extern int advice_push_non_ff_matching; extern int advice_push_non_ff_matching;
@ -12,9 +13,11 @@ extern int advice_push_needs_force;
extern int advice_push_unqualified_ref_name; extern int advice_push_unqualified_ref_name;
extern int advice_status_hints; extern int advice_status_hints;
extern int advice_status_u_option; extern int advice_status_u_option;
extern int advice_status_ahead_behind_warning;
extern int advice_commit_before_merge; extern int advice_commit_before_merge;
extern int advice_reset_quiet_warning; extern int advice_reset_quiet_warning;
extern int advice_resolve_conflict; extern int advice_resolve_conflict;
extern int advice_sequencer_in_use;
extern int advice_implicit_identity; extern int advice_implicit_identity;
extern int advice_detached_head; extern int advice_detached_head;
extern int advice_set_upstream_failure; extern int advice_set_upstream_failure;

180
apply.c
View File

@ -22,6 +22,12 @@
#include "rerere.h" #include "rerere.h"
#include "apply.h" #include "apply.h"
struct gitdiff_data {
struct strbuf *root;
int linenr;
int p_value;
};
static void git_apply_config(void) static void git_apply_config(void)
{ {
git_config_get_string_const("apply.whitespace", &apply_default_whitespace); git_config_get_string_const("apply.whitespace", &apply_default_whitespace);
@ -201,40 +207,6 @@ struct fragment {
#define BINARY_DELTA_DEFLATED 1 #define BINARY_DELTA_DEFLATED 1
#define BINARY_LITERAL_DEFLATED 2 #define BINARY_LITERAL_DEFLATED 2
/*
* This represents a "patch" to a file, both metainfo changes
* such as creation/deletion, filemode and content changes represented
* as a series of fragments.
*/
struct patch {
char *new_name, *old_name, *def_name;
unsigned int old_mode, new_mode;
int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */
int rejected;
unsigned ws_rule;
int lines_added, lines_deleted;
int score;
int extension_linenr; /* first line specifying delete/new/rename/copy */
unsigned int is_toplevel_relative:1;
unsigned int inaccurate_eof:1;
unsigned int is_binary:1;
unsigned int is_copy:1;
unsigned int is_rename:1;
unsigned int recount:1;
unsigned int conflicted_threeway:1;
unsigned int direct_to_threeway:1;
unsigned int crlf_in_old:1;
struct fragment *fragments;
char *result;
size_t resultsize;
char old_oid_prefix[GIT_MAX_HEXSZ + 1];
char new_oid_prefix[GIT_MAX_HEXSZ + 1];
struct patch *next;
/* three-way fallback result */
struct object_id threeway_stage[3];
};
static void free_fragment_list(struct fragment *list) static void free_fragment_list(struct fragment *list)
{ {
while (list) { while (list) {
@ -469,7 +441,7 @@ static char *squash_slash(char *name)
return name; return name;
} }
static char *find_name_gnu(struct apply_state *state, static char *find_name_gnu(struct strbuf *root,
const char *line, const char *line,
int p_value) int p_value)
{ {
@ -478,7 +450,7 @@ static char *find_name_gnu(struct apply_state *state,
/* /*
* Proposed "new-style" GNU patch/diff format; see * Proposed "new-style" GNU patch/diff format; see
* http://marc.info/?l=git&m=112927316408690&w=2 * https://public-inbox.org/git/7vll0wvb2a.fsf@assigned-by-dhcp.cox.net/
*/ */
if (unquote_c_style(&name, line, NULL)) { if (unquote_c_style(&name, line, NULL)) {
strbuf_release(&name); strbuf_release(&name);
@ -495,8 +467,8 @@ static char *find_name_gnu(struct apply_state *state,
} }
strbuf_remove(&name, 0, cp - name.buf); strbuf_remove(&name, 0, cp - name.buf);
if (state->root.len) if (root->len)
strbuf_insert(&name, 0, state->root.buf, state->root.len); strbuf_insert(&name, 0, root->buf, root->len);
return squash_slash(strbuf_detach(&name, NULL)); return squash_slash(strbuf_detach(&name, NULL));
} }
@ -659,7 +631,7 @@ static size_t diff_timestamp_len(const char *line, size_t len)
return line + len - end; return line + len - end;
} }
static char *find_name_common(struct apply_state *state, static char *find_name_common(struct strbuf *root,
const char *line, const char *line,
const char *def, const char *def,
int p_value, int p_value,
@ -702,30 +674,30 @@ static char *find_name_common(struct apply_state *state,
return squash_slash(xstrdup(def)); return squash_slash(xstrdup(def));
} }
if (state->root.len) { if (root->len) {
char *ret = xstrfmt("%s%.*s", state->root.buf, len, start); char *ret = xstrfmt("%s%.*s", root->buf, len, start);
return squash_slash(ret); return squash_slash(ret);
} }
return squash_slash(xmemdupz(start, len)); return squash_slash(xmemdupz(start, len));
} }
static char *find_name(struct apply_state *state, static char *find_name(struct strbuf *root,
const char *line, const char *line,
char *def, char *def,
int p_value, int p_value,
int terminate) int terminate)
{ {
if (*line == '"') { if (*line == '"') {
char *name = find_name_gnu(state, line, p_value); char *name = find_name_gnu(root, line, p_value);
if (name) if (name)
return name; return name;
} }
return find_name_common(state, line, def, p_value, NULL, terminate); return find_name_common(root, line, def, p_value, NULL, terminate);
} }
static char *find_name_traditional(struct apply_state *state, static char *find_name_traditional(struct strbuf *root,
const char *line, const char *line,
char *def, char *def,
int p_value) int p_value)
@ -734,7 +706,7 @@ static char *find_name_traditional(struct apply_state *state,
size_t date_len; size_t date_len;
if (*line == '"') { if (*line == '"') {
char *name = find_name_gnu(state, line, p_value); char *name = find_name_gnu(root, line, p_value);
if (name) if (name)
return name; return name;
} }
@ -742,10 +714,10 @@ static char *find_name_traditional(struct apply_state *state,
len = strchrnul(line, '\n') - line; len = strchrnul(line, '\n') - line;
date_len = diff_timestamp_len(line, len); date_len = diff_timestamp_len(line, len);
if (!date_len) if (!date_len)
return find_name_common(state, line, def, p_value, NULL, TERM_TAB); return find_name_common(root, line, def, p_value, NULL, TERM_TAB);
len -= date_len; len -= date_len;
return find_name_common(state, line, def, p_value, line + len, 0); return find_name_common(root, line, def, p_value, line + len, 0);
} }
/* /*
@ -759,7 +731,7 @@ static int guess_p_value(struct apply_state *state, const char *nameline)
if (is_dev_null(nameline)) if (is_dev_null(nameline))
return -1; return -1;
name = find_name_traditional(state, nameline, NULL, 0); name = find_name_traditional(&state->root, nameline, NULL, 0);
if (!name) if (!name)
return -1; return -1;
cp = strchr(name, '/'); cp = strchr(name, '/');
@ -883,17 +855,17 @@ static int parse_traditional_patch(struct apply_state *state,
if (is_dev_null(first)) { if (is_dev_null(first)) {
patch->is_new = 1; patch->is_new = 1;
patch->is_delete = 0; patch->is_delete = 0;
name = find_name_traditional(state, second, NULL, state->p_value); name = find_name_traditional(&state->root, second, NULL, state->p_value);
patch->new_name = name; patch->new_name = name;
} else if (is_dev_null(second)) { } else if (is_dev_null(second)) {
patch->is_new = 0; patch->is_new = 0;
patch->is_delete = 1; patch->is_delete = 1;
name = find_name_traditional(state, first, NULL, state->p_value); name = find_name_traditional(&state->root, first, NULL, state->p_value);
patch->old_name = name; patch->old_name = name;
} else { } else {
char *first_name; char *first_name;
first_name = find_name_traditional(state, first, NULL, state->p_value); first_name = find_name_traditional(&state->root, first, NULL, state->p_value);
name = find_name_traditional(state, second, first_name, state->p_value); name = find_name_traditional(&state->root, second, first_name, state->p_value);
free(first_name); free(first_name);
if (has_epoch_timestamp(first)) { if (has_epoch_timestamp(first)) {
patch->is_new = 1; patch->is_new = 1;
@ -914,7 +886,7 @@ static int parse_traditional_patch(struct apply_state *state,
return 0; return 0;
} }
static int gitdiff_hdrend(struct apply_state *state, static int gitdiff_hdrend(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -933,14 +905,14 @@ static int gitdiff_hdrend(struct apply_state *state,
#define DIFF_OLD_NAME 0 #define DIFF_OLD_NAME 0
#define DIFF_NEW_NAME 1 #define DIFF_NEW_NAME 1
static int gitdiff_verify_name(struct apply_state *state, static int gitdiff_verify_name(struct gitdiff_data *state,
const char *line, const char *line,
int isnull, int isnull,
char **name, char **name,
int side) int side)
{ {
if (!*name && !isnull) { if (!*name && !isnull) {
*name = find_name(state, line, NULL, state->p_value, TERM_TAB); *name = find_name(state->root, line, NULL, state->p_value, TERM_TAB);
return 0; return 0;
} }
@ -949,7 +921,7 @@ static int gitdiff_verify_name(struct apply_state *state,
if (isnull) if (isnull)
return error(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"), return error(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
*name, state->linenr); *name, state->linenr);
another = find_name(state, line, NULL, state->p_value, TERM_TAB); another = find_name(state->root, line, NULL, state->p_value, TERM_TAB);
if (!another || strcmp(another, *name)) { if (!another || strcmp(another, *name)) {
free(another); free(another);
return error((side == DIFF_NEW_NAME) ? return error((side == DIFF_NEW_NAME) ?
@ -965,7 +937,7 @@ static int gitdiff_verify_name(struct apply_state *state,
return 0; return 0;
} }
static int gitdiff_oldname(struct apply_state *state, static int gitdiff_oldname(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -974,7 +946,7 @@ static int gitdiff_oldname(struct apply_state *state,
DIFF_OLD_NAME); DIFF_OLD_NAME);
} }
static int gitdiff_newname(struct apply_state *state, static int gitdiff_newname(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -992,21 +964,21 @@ static int parse_mode_line(const char *line, int linenr, unsigned int *mode)
return 0; return 0;
} }
static int gitdiff_oldmode(struct apply_state *state, static int gitdiff_oldmode(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
return parse_mode_line(line, state->linenr, &patch->old_mode); return parse_mode_line(line, state->linenr, &patch->old_mode);
} }
static int gitdiff_newmode(struct apply_state *state, static int gitdiff_newmode(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
return parse_mode_line(line, state->linenr, &patch->new_mode); return parse_mode_line(line, state->linenr, &patch->new_mode);
} }
static int gitdiff_delete(struct apply_state *state, static int gitdiff_delete(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1016,7 +988,7 @@ static int gitdiff_delete(struct apply_state *state,
return gitdiff_oldmode(state, line, patch); return gitdiff_oldmode(state, line, patch);
} }
static int gitdiff_newfile(struct apply_state *state, static int gitdiff_newfile(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1026,47 +998,47 @@ static int gitdiff_newfile(struct apply_state *state,
return gitdiff_newmode(state, line, patch); return gitdiff_newmode(state, line, patch);
} }
static int gitdiff_copysrc(struct apply_state *state, static int gitdiff_copysrc(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
patch->is_copy = 1; patch->is_copy = 1;
free(patch->old_name); free(patch->old_name);
patch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0); patch->old_name = find_name(state->root, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_copydst(struct apply_state *state, static int gitdiff_copydst(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
patch->is_copy = 1; patch->is_copy = 1;
free(patch->new_name); free(patch->new_name);
patch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0); patch->new_name = find_name(state->root, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_renamesrc(struct apply_state *state, static int gitdiff_renamesrc(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
patch->is_rename = 1; patch->is_rename = 1;
free(patch->old_name); free(patch->old_name);
patch->old_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0); patch->old_name = find_name(state->root, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_renamedst(struct apply_state *state, static int gitdiff_renamedst(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
patch->is_rename = 1; patch->is_rename = 1;
free(patch->new_name); free(patch->new_name);
patch->new_name = find_name(state, line, NULL, state->p_value ? state->p_value - 1 : 0, 0); patch->new_name = find_name(state->root, line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
return 0; return 0;
} }
static int gitdiff_similarity(struct apply_state *state, static int gitdiff_similarity(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1076,7 +1048,7 @@ static int gitdiff_similarity(struct apply_state *state,
return 0; return 0;
} }
static int gitdiff_dissimilarity(struct apply_state *state, static int gitdiff_dissimilarity(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1086,7 +1058,7 @@ static int gitdiff_dissimilarity(struct apply_state *state,
return 0; return 0;
} }
static int gitdiff_index(struct apply_state *state, static int gitdiff_index(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1126,7 +1098,7 @@ static int gitdiff_index(struct apply_state *state,
* This is normal for a diff that doesn't change anything: we'll fall through * This is normal for a diff that doesn't change anything: we'll fall through
* into the next diff. Tell the parser to break out. * into the next diff. Tell the parser to break out.
*/ */
static int gitdiff_unrecognized(struct apply_state *state, static int gitdiff_unrecognized(struct gitdiff_data *state,
const char *line, const char *line,
struct patch *patch) struct patch *patch)
{ {
@ -1137,17 +1109,17 @@ static int gitdiff_unrecognized(struct apply_state *state,
* Skip p_value leading components from "line"; as we do not accept * Skip p_value leading components from "line"; as we do not accept
* absolute paths, return NULL in that case. * absolute paths, return NULL in that case.
*/ */
static const char *skip_tree_prefix(struct apply_state *state, static const char *skip_tree_prefix(int p_value,
const char *line, const char *line,
int llen) int llen)
{ {
int nslash; int nslash;
int i; int i;
if (!state->p_value) if (!p_value)
return (llen && line[0] == '/') ? NULL : line; return (llen && line[0] == '/') ? NULL : line;
nslash = state->p_value; nslash = p_value;
for (i = 0; i < llen; i++) { for (i = 0; i < llen; i++) {
int ch = line[i]; int ch = line[i];
if (ch == '/' && --nslash <= 0) if (ch == '/' && --nslash <= 0)
@ -1164,7 +1136,7 @@ static const char *skip_tree_prefix(struct apply_state *state,
* creation or deletion of an empty file. In any of these cases, * creation or deletion of an empty file. In any of these cases,
* both sides are the same name under a/ and b/ respectively. * both sides are the same name under a/ and b/ respectively.
*/ */
static char *git_header_name(struct apply_state *state, static char *git_header_name(int p_value,
const char *line, const char *line,
int llen) int llen)
{ {
@ -1184,7 +1156,7 @@ static char *git_header_name(struct apply_state *state,
goto free_and_fail1; goto free_and_fail1;
/* strip the a/b prefix including trailing slash */ /* strip the a/b prefix including trailing slash */
cp = skip_tree_prefix(state, first.buf, first.len); cp = skip_tree_prefix(p_value, first.buf, first.len);
if (!cp) if (!cp)
goto free_and_fail1; goto free_and_fail1;
strbuf_remove(&first, 0, cp - first.buf); strbuf_remove(&first, 0, cp - first.buf);
@ -1201,7 +1173,7 @@ static char *git_header_name(struct apply_state *state,
if (*second == '"') { if (*second == '"') {
if (unquote_c_style(&sp, second, NULL)) if (unquote_c_style(&sp, second, NULL))
goto free_and_fail1; goto free_and_fail1;
cp = skip_tree_prefix(state, sp.buf, sp.len); cp = skip_tree_prefix(p_value, sp.buf, sp.len);
if (!cp) if (!cp)
goto free_and_fail1; goto free_and_fail1;
/* They must match, otherwise ignore */ /* They must match, otherwise ignore */
@ -1212,7 +1184,7 @@ static char *git_header_name(struct apply_state *state,
} }
/* unquoted second */ /* unquoted second */
cp = skip_tree_prefix(state, second, line + llen - second); cp = skip_tree_prefix(p_value, second, line + llen - second);
if (!cp) if (!cp)
goto free_and_fail1; goto free_and_fail1;
if (line + llen - cp != first.len || if (line + llen - cp != first.len ||
@ -1227,7 +1199,7 @@ static char *git_header_name(struct apply_state *state,
} }
/* unquoted first name */ /* unquoted first name */
name = skip_tree_prefix(state, line, llen); name = skip_tree_prefix(p_value, line, llen);
if (!name) if (!name)
return NULL; return NULL;
@ -1243,7 +1215,7 @@ static char *git_header_name(struct apply_state *state,
if (unquote_c_style(&sp, second, NULL)) if (unquote_c_style(&sp, second, NULL))
goto free_and_fail2; goto free_and_fail2;
np = skip_tree_prefix(state, sp.buf, sp.len); np = skip_tree_prefix(p_value, sp.buf, sp.len);
if (!np) if (!np)
goto free_and_fail2; goto free_and_fail2;
@ -1287,7 +1259,7 @@ static char *git_header_name(struct apply_state *state,
*/ */
if (!name[len + 1]) if (!name[len + 1])
return NULL; /* no postimage name */ return NULL; /* no postimage name */
second = skip_tree_prefix(state, name + len + 1, second = skip_tree_prefix(p_value, name + len + 1,
line_len - (len + 1)); line_len - (len + 1));
if (!second) if (!second)
return NULL; return NULL;
@ -1302,26 +1274,28 @@ static char *git_header_name(struct apply_state *state,
} }
} }
static int check_header_line(struct apply_state *state, struct patch *patch) static int check_header_line(int linenr, struct patch *patch)
{ {
int extensions = (patch->is_delete == 1) + (patch->is_new == 1) + int extensions = (patch->is_delete == 1) + (patch->is_new == 1) +
(patch->is_rename == 1) + (patch->is_copy == 1); (patch->is_rename == 1) + (patch->is_copy == 1);
if (extensions > 1) if (extensions > 1)
return error(_("inconsistent header lines %d and %d"), return error(_("inconsistent header lines %d and %d"),
patch->extension_linenr, state->linenr); patch->extension_linenr, linenr);
if (extensions && !patch->extension_linenr) if (extensions && !patch->extension_linenr)
patch->extension_linenr = state->linenr; patch->extension_linenr = linenr;
return 0; return 0;
} }
/* Verify that we recognize the lines following a git header */ int parse_git_diff_header(struct strbuf *root,
static int parse_git_header(struct apply_state *state, int *linenr,
int p_value,
const char *line, const char *line,
int len, int len,
unsigned int size, unsigned int size,
struct patch *patch) struct patch *patch)
{ {
unsigned long offset; unsigned long offset;
struct gitdiff_data parse_hdr_state;
/* A git diff has explicit new/delete information, so we don't guess */ /* A git diff has explicit new/delete information, so we don't guess */
patch->is_new = 0; patch->is_new = 0;
@ -1333,20 +1307,24 @@ static int parse_git_header(struct apply_state *state,
* or removing or adding empty files), so we get * or removing or adding empty files), so we get
* the default name from the header. * the default name from the header.
*/ */
patch->def_name = git_header_name(state, line, len); patch->def_name = git_header_name(p_value, line, len);
if (patch->def_name && state->root.len) { if (patch->def_name && root->len) {
char *s = xstrfmt("%s%s", state->root.buf, patch->def_name); char *s = xstrfmt("%s%s", root->buf, patch->def_name);
free(patch->def_name); free(patch->def_name);
patch->def_name = s; patch->def_name = s;
} }
line += len; line += len;
size -= len; size -= len;
state->linenr++; (*linenr)++;
for (offset = len ; size > 0 ; offset += len, size -= len, line += len, state->linenr++) { parse_hdr_state.root = root;
parse_hdr_state.linenr = *linenr;
parse_hdr_state.p_value = p_value;
for (offset = len ; size > 0 ; offset += len, size -= len, line += len, (*linenr)++) {
static const struct opentry { static const struct opentry {
const char *str; const char *str;
int (*fn)(struct apply_state *, const char *, struct patch *); int (*fn)(struct gitdiff_data *, const char *, struct patch *);
} optable[] = { } optable[] = {
{ "@@ -", gitdiff_hdrend }, { "@@ -", gitdiff_hdrend },
{ "--- ", gitdiff_oldname }, { "--- ", gitdiff_oldname },
@ -1377,10 +1355,10 @@ static int parse_git_header(struct apply_state *state,
int res; int res;
if (len < oplen || memcmp(p->str, line, oplen)) if (len < oplen || memcmp(p->str, line, oplen))
continue; continue;
res = p->fn(state, line + oplen, patch); res = p->fn(&parse_hdr_state, line + oplen, patch);
if (res < 0) if (res < 0)
return -1; return -1;
if (check_header_line(state, patch)) if (check_header_line(*linenr, patch))
return -1; return -1;
if (res > 0) if (res > 0)
return offset; return offset;
@ -1561,7 +1539,9 @@ static int find_header(struct apply_state *state,
* or mode change, so we handle that specially * or mode change, so we handle that specially
*/ */
if (!memcmp("diff --git ", line, 11)) { if (!memcmp("diff --git ", line, 11)) {
int git_hdr_len = parse_git_header(state, line, len, size, patch); int git_hdr_len = parse_git_diff_header(&state->root, &state->linenr,
state->p_value, line, len,
size, patch);
if (git_hdr_len < 0) if (git_hdr_len < 0)
return -128; return -128;
if (git_hdr_len <= len) if (git_hdr_len <= len)
@ -4310,7 +4290,7 @@ static int add_index_file(struct apply_state *state,
"created file '%s'"), "created file '%s'"),
path); path);
} }
fill_stat_cache_info(ce, &st); fill_stat_cache_info(state->repo->index, ce, &st);
} }
if (write_object_file(buf, size, blob_type, &ce->oid) < 0) { if (write_object_file(buf, size, blob_type, &ce->oid) < 0) {
discard_cache_entry(ce); discard_cache_entry(ce);

48
apply.h
View File

@ -117,6 +117,40 @@ struct apply_state {
int applied_after_fixing_ws; int applied_after_fixing_ws;
}; };
/*
* This represents a "patch" to a file, both metainfo changes
* such as creation/deletion, filemode and content changes represented
* as a series of fragments.
*/
struct patch {
char *new_name, *old_name, *def_name;
unsigned int old_mode, new_mode;
int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */
int rejected;
unsigned ws_rule;
int lines_added, lines_deleted;
int score;
int extension_linenr; /* first line specifying delete/new/rename/copy */
unsigned int is_toplevel_relative:1;
unsigned int inaccurate_eof:1;
unsigned int is_binary:1;
unsigned int is_copy:1;
unsigned int is_rename:1;
unsigned int recount:1;
unsigned int conflicted_threeway:1;
unsigned int direct_to_threeway:1;
unsigned int crlf_in_old:1;
struct fragment *fragments;
char *result;
size_t resultsize;
char old_oid_prefix[GIT_MAX_HEXSZ + 1];
char new_oid_prefix[GIT_MAX_HEXSZ + 1];
struct patch *next;
/* three-way fallback result */
struct object_id threeway_stage[3];
};
int apply_parse_options(int argc, const char **argv, int apply_parse_options(int argc, const char **argv,
struct apply_state *state, struct apply_state *state,
int *force_apply, int *options, int *force_apply, int *options,
@ -127,6 +161,20 @@ int init_apply_state(struct apply_state *state,
void clear_apply_state(struct apply_state *state); void clear_apply_state(struct apply_state *state);
int check_apply_state(struct apply_state *state, int force_apply); int check_apply_state(struct apply_state *state, int force_apply);
/*
* Parse a git diff header, starting at line. Fills the relevant
* metadata information in 'struct patch'.
*
* Returns -1 on failure, the length of the parsed header otherwise.
*/
int parse_git_diff_header(struct strbuf *root,
int *linenr,
int p_value,
const char *line,
int len,
unsigned int size,
struct patch *patch);
/* /*
* Some aspects of the apply behavior are controlled by the following * Some aspects of the apply behavior are controlled by the following
* bits in the "options" parameter passed to apply_all_patches(). * bits in the "options" parameter passed to apply_all_patches().

View File

@ -418,7 +418,9 @@ static void parse_treeish_arg(const char **argv,
unsigned short mode; unsigned short mode;
int err; int err;
err = get_tree_entry(&tree->object.oid, prefix, &tree_oid, err = get_tree_entry(ar_args->repo,
&tree->object.oid,
prefix, &tree_oid,
&mode); &mode);
if (err || !S_ISDIR(mode)) if (err || !S_ISDIR(mode))
die(_("current working directory is untracked")); die(_("current working directory is untracked"));

1015
blame.c

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,8 @@ struct blame_origin {
*/ */
struct blame_entry *suspects; struct blame_entry *suspects;
mmfile_t file; mmfile_t file;
int num_lines;
void *fingerprints;
struct object_id blob_oid; struct object_id blob_oid;
unsigned short mode; unsigned short mode;
/* guilty gets set when shipping any suspects to the final /* guilty gets set when shipping any suspects to the final
@ -92,6 +94,8 @@ struct blame_entry {
* scanning the lines over and over. * scanning the lines over and over.
*/ */
unsigned score; unsigned score;
int ignored;
int unblamable;
}; };
/* /*
@ -117,6 +121,8 @@ struct blame_scoreboard {
/* linked list of blames */ /* linked list of blames */
struct blame_entry *ent; struct blame_entry *ent;
struct oidset ignore_list;
/* look-up a line in the final buffer */ /* look-up a line in the final buffer */
int num_lines; int num_lines;
int *lineno; int *lineno;

5
blob.c
View File

@ -7,10 +7,9 @@ const char *blob_type = "blob";
struct blob *lookup_blob(struct repository *r, const struct object_id *oid) struct blob *lookup_blob(struct repository *r, const struct object_id *oid)
{ {
struct object *obj = lookup_object(r, oid->hash); struct object *obj = lookup_object(r, oid);
if (!obj) if (!obj)
return create_object(r, oid->hash, return create_object(r, oid, alloc_blob_node(r));
alloc_blob_node(r));
return object_as_type(r, obj, OBJ_BLOB, 0); return object_as_type(r, obj, OBJ_BLOB, 0);
} }

View File

@ -338,14 +338,19 @@ void create_branch(struct repository *r,
free(real_ref); free(real_ref);
} }
void remove_branch_state(struct repository *r) void remove_merge_branch_state(struct repository *r)
{ {
sequencer_post_commit_cleanup(r);
unlink(git_path_merge_head(r)); unlink(git_path_merge_head(r));
unlink(git_path_merge_rr(r)); unlink(git_path_merge_rr(r));
unlink(git_path_merge_msg(r)); unlink(git_path_merge_msg(r));
unlink(git_path_merge_mode(r)); unlink(git_path_merge_mode(r));
}
void remove_branch_state(struct repository *r, int verbose)
{
sequencer_post_commit_cleanup(r, verbose);
unlink(git_path_squash_msg(r)); unlink(git_path_squash_msg(r));
remove_merge_branch_state(r);
} }
void die_if_checked_out(const char *branch, int ignore_current_worktree) void die_if_checked_out(const char *branch, int ignore_current_worktree)

View File

@ -60,11 +60,17 @@ int validate_branchname(const char *name, struct strbuf *ref);
*/ */
int validate_new_branchname(const char *name, struct strbuf *ref, int force); int validate_new_branchname(const char *name, struct strbuf *ref, int force);
/*
* Remove information about the merge state on the current
* branch. (E.g., MERGE_HEAD)
*/
void remove_merge_branch_state(struct repository *r);
/* /*
* Remove information about the state of working on the current * Remove information about the state of working on the current
* branch. (E.g., MERGE_HEAD) * branch. (E.g., MERGE_HEAD)
*/ */
void remove_branch_state(struct repository *r); void remove_branch_state(struct repository *r, int verbose);
/* /*
* Configure local branch "local" as downstream to branch "remote" * Configure local branch "local" as downstream to branch "remote"

View File

@ -160,6 +160,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix);
int cmd_diff(int argc, const char **argv, const char *prefix); int cmd_diff(int argc, const char **argv, const char *prefix);
int cmd_diff_tree(int argc, const char **argv, const char *prefix); int cmd_diff_tree(int argc, const char **argv, const char *prefix);
int cmd_difftool(int argc, const char **argv, const char *prefix); int cmd_difftool(int argc, const char **argv, const char *prefix);
int cmd_env__helper(int argc, const char **argv, const char *prefix);
int cmd_fast_export(int argc, const char **argv, const char *prefix); int cmd_fast_export(int argc, const char **argv, const char *prefix);
int cmd_fetch(int argc, const char **argv, const char *prefix); int cmd_fetch(int argc, const char **argv, const char *prefix);
int cmd_fetch_pack(int argc, const char **argv, const char *prefix); int cmd_fetch_pack(int argc, const char **argv, const char *prefix);
@ -214,6 +215,7 @@ int cmd_remote_fd(int argc, const char **argv, const char *prefix);
int cmd_repack(int argc, const char **argv, const char *prefix); int cmd_repack(int argc, const char **argv, const char *prefix);
int cmd_rerere(int argc, const char **argv, const char *prefix); int cmd_rerere(int argc, const char **argv, const char *prefix);
int cmd_reset(int argc, const char **argv, const char *prefix); int cmd_reset(int argc, const char **argv, const char *prefix);
int cmd_restore(int argc, const char **argv, const char *prefix);
int cmd_rev_list(int argc, const char **argv, const char *prefix); int cmd_rev_list(int argc, const char **argv, const char *prefix);
int cmd_rev_parse(int argc, const char **argv, const char *prefix); int cmd_rev_parse(int argc, const char **argv, const char *prefix);
int cmd_revert(int argc, const char **argv, const char *prefix); int cmd_revert(int argc, const char **argv, const char *prefix);
@ -227,6 +229,7 @@ int cmd_status(int argc, const char **argv, const char *prefix);
int cmd_stash(int argc, const char **argv, const char *prefix); int cmd_stash(int argc, const char **argv, const char *prefix);
int cmd_stripspace(int argc, const char **argv, const char *prefix); int cmd_stripspace(int argc, const char **argv, const char *prefix);
int cmd_submodule__helper(int argc, const char **argv, const char *prefix); int cmd_submodule__helper(int argc, const char **argv, const char *prefix);
int cmd_switch(int argc, const char **argv, const char *prefix);
int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
int cmd_tag(int argc, const char **argv, const char *prefix); int cmd_tag(int argc, const char **argv, const char *prefix);
int cmd_tar_tree(int argc, const char **argv, const char *prefix); int cmd_tar_tree(int argc, const char **argv, const char *prefix);

View File

@ -1339,9 +1339,10 @@ static void write_index_patch(const struct am_state *state)
struct rev_info rev_info; struct rev_info rev_info;
FILE *fp; FILE *fp;
if (!get_oid_tree("HEAD", &head)) if (!get_oid("HEAD", &head)) {
tree = lookup_tree(the_repository, &head); struct commit *commit = lookup_commit_or_die(&head, "HEAD");
else tree = get_commit_tree(commit);
} else
tree = lookup_tree(the_repository, tree = lookup_tree(the_repository,
the_repository->hash_algo->empty_tree); the_repository->hash_algo->empty_tree);
@ -1643,11 +1644,8 @@ static int do_interactive(struct am_state *state)
{ {
assert(state->msg); assert(state->msg);
if (!isatty(0))
die(_("cannot be interactive without stdin connected to a terminal."));
for (;;) { for (;;) {
const char *reply; char reply[64];
puts(_("Commit Body is:")); puts(_("Commit Body is:"));
puts("--------------------------"); puts("--------------------------");
@ -1659,11 +1657,11 @@ static int do_interactive(struct am_state *state)
* in your translation. The program will only accept English * in your translation. The program will only accept English
* input at this point. * input at this point.
*/ */
reply = git_prompt(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "), PROMPT_ECHO); printf(_("Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "));
if (!fgets(reply, sizeof(reply), stdin))
die("unable to read from stdin; aborting");
if (!reply) { if (*reply == 'y' || *reply == 'Y') {
continue;
} else if (*reply == 'y' || *reply == 'Y') {
return 0; return 0;
} else if (*reply == 'a' || *reply == 'A') { } else if (*reply == 'a' || *reply == 'A') {
state->interactive = 0; state->interactive = 0;
@ -1803,7 +1801,7 @@ next:
*/ */
if (!state->rebasing) { if (!state->rebasing) {
am_destroy(state); am_destroy(state);
close_all_packs(the_repository->objects); close_object_store(the_repository->objects);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
} }
} }
@ -1958,7 +1956,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
if (merge_tree(remote_tree)) if (merge_tree(remote_tree))
return -1; return -1;
remove_branch_state(the_repository); remove_branch_state(the_repository, 0);
return 0; return 0;
} }
@ -2334,6 +2332,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
argv_array_push(&paths, mkpath("%s/%s", prefix, argv[i])); argv_array_push(&paths, mkpath("%s/%s", prefix, argv[i]));
} }
if (state.interactive && !paths.argc)
die(_("interactive mode requires patches on the command line"));
am_setup(&state, patch_format, paths.argv, keep_cr); am_setup(&state, patch_format, paths.argv, keep_cr);
argv_array_clear(&paths); argv_array_clear(&paths);

View File

@ -570,7 +570,10 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
write_file(git_path_bisect_start(), "%s\n", start_head.buf); write_file(git_path_bisect_start(), "%s\n", start_head.buf);
if (no_checkout) { if (no_checkout) {
get_oid(start_head.buf, &oid); if (get_oid(start_head.buf, &oid) < 0) {
retval = error(_("invalid ref: '%s'"), start_head.buf);
goto finish;
}
if (update_ref(NULL, "BISECT_HEAD", &oid, NULL, 0, if (update_ref(NULL, "BISECT_HEAD", &oid, NULL, 0,
UPDATE_REFS_MSG_ON_ERR)) { UPDATE_REFS_MSG_ON_ERR)) {
retval = -1; retval = -1;

View File

@ -53,14 +53,17 @@ static int no_whole_file_rename;
static int show_progress; static int show_progress;
static char repeated_meta_color[COLOR_MAXLEN]; static char repeated_meta_color[COLOR_MAXLEN];
static int coloring_mode; static int coloring_mode;
static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP;
static int mark_unblamable_lines;
static int mark_ignored_lines;
static struct date_mode blame_date_mode = { DATE_ISO8601 }; static struct date_mode blame_date_mode = { DATE_ISO8601 };
static size_t blame_date_width; static size_t blame_date_width;
static struct string_list mailmap = STRING_LIST_INIT_NODUP; static struct string_list mailmap = STRING_LIST_INIT_NODUP;
#ifndef DEBUG #ifndef DEBUG_BLAME
#define DEBUG 0 #define DEBUG_BLAME 0
#endif #endif
static unsigned blame_move_score; static unsigned blame_move_score;
@ -480,6 +483,14 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
} }
} }
if (mark_unblamable_lines && ent->unblamable) {
length--;
putchar('*');
}
if (mark_ignored_lines && ent->ignored) {
length--;
putchar('?');
}
printf("%.*s", length, hex); printf("%.*s", length, hex);
if (opt & OUTPUT_ANNOTATE_COMPAT) { if (opt & OUTPUT_ANNOTATE_COMPAT) {
const char *name; const char *name;
@ -696,6 +707,24 @@ static int git_blame_config(const char *var, const char *value, void *cb)
parse_date_format(value, &blame_date_mode); parse_date_format(value, &blame_date_mode);
return 0; return 0;
} }
if (!strcmp(var, "blame.ignorerevsfile")) {
const char *str;
int ret;
ret = git_config_pathname(&str, var, value);
if (ret)
return ret;
string_list_insert(&ignore_revs_file_list, str);
return 0;
}
if (!strcmp(var, "blame.markunblamablelines")) {
mark_unblamable_lines = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "blame.markignoredlines")) {
mark_ignored_lines = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "color.blame.repeatedlines")) { if (!strcmp(var, "color.blame.repeatedlines")) {
if (color_parse_mem(value, strlen(value), repeated_meta_color)) if (color_parse_mem(value, strlen(value), repeated_meta_color))
warning(_("invalid color '%s' in color.blame.repeatedLines"), warning(_("invalid color '%s' in color.blame.repeatedLines"),
@ -775,6 +804,27 @@ static int is_a_rev(const char *name)
return OBJ_NONE < oid_object_info(the_repository, &oid, NULL); return OBJ_NONE < oid_object_info(the_repository, &oid, NULL);
} }
static void build_ignorelist(struct blame_scoreboard *sb,
struct string_list *ignore_revs_file_list,
struct string_list *ignore_rev_list)
{
struct string_list_item *i;
struct object_id oid;
oidset_init(&sb->ignore_list, 0);
for_each_string_list_item(i, ignore_revs_file_list) {
if (!strcmp(i->string, ""))
oidset_clear(&sb->ignore_list);
else
oidset_parse_file(&sb->ignore_list, i->string);
}
for_each_string_list_item(i, ignore_rev_list) {
if (get_oid_committish(i->string, &oid))
die(_("cannot find revision %s to ignore"), i->string);
oidset_insert(&sb->ignore_list, &oid);
}
}
int cmd_blame(int argc, const char **argv, const char *prefix) int cmd_blame(int argc, const char **argv, const char *prefix)
{ {
struct rev_info revs; struct rev_info revs;
@ -786,6 +836,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
struct progress_info pi = { NULL, 0 }; struct progress_info pi = { NULL, 0 };
struct string_list range_list = STRING_LIST_INIT_NODUP; struct string_list range_list = STRING_LIST_INIT_NODUP;
struct string_list ignore_rev_list = STRING_LIST_INIT_NODUP;
int output_option = 0, opt = 0; int output_option = 0, opt = 0;
int show_stats = 0; int show_stats = 0;
const char *revs_file = NULL; const char *revs_file = NULL;
@ -807,6 +858,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR), OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL), OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE), OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
OPT_STRING_LIST(0, "ignore-rev", &ignore_rev_list, N_("rev"), N_("Ignore <rev> when blaming")),
OPT_STRING_LIST(0, "ignore-revs-file", &ignore_revs_file_list, N_("file"), N_("Ignore revisions from <file>")),
OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE), OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),
OPT_BIT(0, "color-by-age", &output_option, N_("color lines by age"), OUTPUT_SHOW_AGE_WITH_COLOR), OPT_BIT(0, "color-by-age", &output_option, N_("color lines by age"), OUTPUT_SHOW_AGE_WITH_COLOR),
@ -1012,6 +1065,9 @@ parse_done:
sb.contents_from = contents_from; sb.contents_from = contents_from;
sb.reverse = reverse; sb.reverse = reverse;
sb.repo = the_repository; sb.repo = the_repository;
build_ignorelist(&sb, &ignore_revs_file_list, &ignore_rev_list);
string_list_clear(&ignore_revs_file_list, 0);
string_list_clear(&ignore_rev_list, 0);
setup_scoreboard(&sb, path, &o); setup_scoreboard(&sb, path, &o);
lno = sb.num_lines; lno = sb.num_lines;
@ -1062,7 +1118,7 @@ parse_done:
if (blame_copy_score) if (blame_copy_score)
sb.copy_score = blame_copy_score; sb.copy_score = blame_copy_score;
sb.debug = DEBUG; sb.debug = DEBUG_BLAME;
sb.on_sanity_fail = &sanity_check_on_fail; sb.on_sanity_fail = &sanity_check_on_fail;
sb.show_root = show_root; sb.show_root = show_root;

View File

@ -47,6 +47,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL, /* LOCAL */ GIT_COLOR_NORMAL, /* LOCAL */
GIT_COLOR_GREEN, /* CURRENT */ GIT_COLOR_GREEN, /* CURRENT */
GIT_COLOR_BLUE, /* UPSTREAM */ GIT_COLOR_BLUE, /* UPSTREAM */
GIT_COLOR_CYAN, /* WORKTREE */
}; };
enum color_branch { enum color_branch {
BRANCH_COLOR_RESET = 0, BRANCH_COLOR_RESET = 0,
@ -54,7 +55,8 @@ enum color_branch {
BRANCH_COLOR_REMOTE = 2, BRANCH_COLOR_REMOTE = 2,
BRANCH_COLOR_LOCAL = 3, BRANCH_COLOR_LOCAL = 3,
BRANCH_COLOR_CURRENT = 4, BRANCH_COLOR_CURRENT = 4,
BRANCH_COLOR_UPSTREAM = 5 BRANCH_COLOR_UPSTREAM = 5,
BRANCH_COLOR_WORKTREE = 6
}; };
static const char *color_branch_slots[] = { static const char *color_branch_slots[] = {
@ -64,6 +66,7 @@ static const char *color_branch_slots[] = {
[BRANCH_COLOR_LOCAL] = "local", [BRANCH_COLOR_LOCAL] = "local",
[BRANCH_COLOR_CURRENT] = "current", [BRANCH_COLOR_CURRENT] = "current",
[BRANCH_COLOR_UPSTREAM] = "upstream", [BRANCH_COLOR_UPSTREAM] = "upstream",
[BRANCH_COLOR_WORKTREE] = "worktree",
}; };
static struct string_list output = STRING_LIST_INIT_DUP; static struct string_list output = STRING_LIST_INIT_DUP;
@ -342,8 +345,9 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
struct strbuf local = STRBUF_INIT; struct strbuf local = STRBUF_INIT;
struct strbuf remote = STRBUF_INIT; struct strbuf remote = STRBUF_INIT;
strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else) %s%%(end)", strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else)%%(if)%%(worktreepath)%%(then)+ %s%%(else) %s%%(end)%%(end)",
branch_get_color(BRANCH_COLOR_CURRENT), branch_get_color(BRANCH_COLOR_CURRENT),
branch_get_color(BRANCH_COLOR_WORKTREE),
branch_get_color(BRANCH_COLOR_LOCAL)); branch_get_color(BRANCH_COLOR_LOCAL));
strbuf_addf(&remote, " %s", strbuf_addf(&remote, " %s",
branch_get_color(BRANCH_COLOR_REMOTE)); branch_get_color(BRANCH_COLOR_REMOTE));
@ -363,9 +367,13 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
strbuf_addf(&local, " %s ", obname.buf); strbuf_addf(&local, " %s ", obname.buf);
if (filter->verbose > 1) if (filter->verbose > 1)
{
strbuf_addf(&local, "%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)",
branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));
strbuf_addf(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)" strbuf_addf(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)"
"%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)", "%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)",
branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET)); branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));
}
else else
strbuf_addf(&local, "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)"); strbuf_addf(&local, "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)");
@ -830,7 +838,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
strbuf_release(&buf); strbuf_release(&buf);
} else if (argc > 0 && argc <= 2) { } else if (argc > 0 && argc <= 2) {
if (filter.kind != FILTER_REFS_BRANCHES) if (filter.kind != FILTER_REFS_BRANCHES)
die(_("-a and -r options to 'git branch' do not make sense with a branch name")); die(_("The -a, and -r, options to 'git branch' do not take a branch name.\n"
"Did you mean to use: -a|-r --list <pattern>?"));
if (track == BRANCH_TRACK_OVERRIDE) if (track == BRANCH_TRACK_OVERRIDE)
die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead.")); die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead."));

View File

@ -172,7 +172,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
* fall-back to the usual case. * fall-back to the usual case.
*/ */
} }
buf = read_object_with_reference(&oid, exp_type, &size, NULL); buf = read_object_with_reference(the_repository,
&oid, exp_type, &size, NULL);
break; break;
default: default:

File diff suppressed because it is too large Load Diff

View File

@ -34,6 +34,7 @@ static const char *msg_would_remove = N_("Would remove %s\n");
static const char *msg_skip_git_dir = N_("Skipping repository %s\n"); static const char *msg_skip_git_dir = N_("Skipping repository %s\n");
static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n"); static const char *msg_would_skip_git_dir = N_("Would skip repository %s\n");
static const char *msg_warn_remove_failed = N_("failed to remove %s"); static const char *msg_warn_remove_failed = N_("failed to remove %s");
static const char *msg_warn_lstat_failed = N_("could not lstat %s\n");
enum color_clean { enum color_clean {
CLEAN_COLOR_RESET = 0, CLEAN_COLOR_RESET = 0,
@ -194,7 +195,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
strbuf_setlen(path, len); strbuf_setlen(path, len);
strbuf_addstr(path, e->d_name); strbuf_addstr(path, e->d_name);
if (lstat(path->buf, &st)) if (lstat(path->buf, &st))
; /* fall thru */ warning_errno(_(msg_warn_lstat_failed), path->buf);
else if (S_ISDIR(st.st_mode)) { else if (S_ISDIR(st.st_mode)) {
if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone)) if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone))
ret = 1; ret = 1;

View File

@ -23,6 +23,8 @@
#include "transport.h" #include "transport.h"
#include "strbuf.h" #include "strbuf.h"
#include "dir.h" #include "dir.h"
#include "dir-iterator.h"
#include "iterator.h"
#include "sigchain.h" #include "sigchain.h"
#include "branch.h" #include "branch.h"
#include "remote.h" #include "remote.h"
@ -67,6 +69,7 @@ static int max_jobs = -1;
static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP; static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP;
static struct list_objects_filter_options filter_options; static struct list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_NODUP; static struct string_list server_options = STRING_LIST_INIT_NODUP;
static int option_remote_submodules;
static int recurse_submodules_cb(const struct option *opt, static int recurse_submodules_cb(const struct option *opt,
const char *arg, int unset) const char *arg, int unset)
@ -142,6 +145,8 @@ static struct option builtin_clone_options[] = {
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
TRANSPORT_FAMILY_IPV6), TRANSPORT_FAMILY_IPV6),
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
OPT_BOOL(0, "remote-submodules", &option_remote_submodules,
N_("any cloned submodules will use their remote-tracking branch")),
OPT_END() OPT_END()
}; };
@ -354,8 +359,7 @@ static void setup_reference(void)
add_one_reference, &required); add_one_reference, &required);
} }
static void copy_alternates(struct strbuf *src, struct strbuf *dst, static void copy_alternates(struct strbuf *src, const char *src_repo)
const char *src_repo)
{ {
/* /*
* Read from the source objects/info/alternates file * Read from the source objects/info/alternates file
@ -392,58 +396,63 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
fclose(in); fclose(in);
} }
static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest, static void mkdir_if_missing(const char *pathname, mode_t mode)
const char *src_repo, int src_baselen)
{ {
struct dirent *de; struct stat st;
struct stat buf;
int src_len, dest_len;
DIR *dir;
dir = opendir(src->buf); if (!mkdir(pathname, mode))
if (!dir) return;
die_errno(_("failed to open '%s'"), src->buf);
if (mkdir(dest->buf, 0777)) {
if (errno != EEXIST) if (errno != EEXIST)
die_errno(_("failed to create directory '%s'"), dest->buf); die_errno(_("failed to create directory '%s'"), pathname);
else if (stat(dest->buf, &buf)) else if (stat(pathname, &st))
die_errno(_("failed to stat '%s'"), dest->buf); die_errno(_("failed to stat '%s'"), pathname);
else if (!S_ISDIR(buf.st_mode)) else if (!S_ISDIR(st.st_mode))
die(_("%s exists and is not a directory"), dest->buf); die(_("%s exists and is not a directory"), pathname);
} }
static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
const char *src_repo)
{
int src_len, dest_len;
struct dir_iterator *iter;
int iter_status;
unsigned int flags;
mkdir_if_missing(dest->buf, 0777);
flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS;
iter = dir_iterator_begin(src->buf, flags);
if (!iter)
die_errno(_("failed to start iterator over '%s'"), src->buf);
strbuf_addch(src, '/'); strbuf_addch(src, '/');
src_len = src->len; src_len = src->len;
strbuf_addch(dest, '/'); strbuf_addch(dest, '/');
dest_len = dest->len; dest_len = dest->len;
while ((de = readdir(dir)) != NULL) { while ((iter_status = dir_iterator_advance(iter)) == ITER_OK) {
strbuf_setlen(src, src_len); strbuf_setlen(src, src_len);
strbuf_addstr(src, de->d_name); strbuf_addstr(src, iter->relative_path);
strbuf_setlen(dest, dest_len); strbuf_setlen(dest, dest_len);
strbuf_addstr(dest, de->d_name); strbuf_addstr(dest, iter->relative_path);
if (stat(src->buf, &buf)) {
warning (_("failed to stat %s\n"), src->buf); if (S_ISDIR(iter->st.st_mode)) {
continue; mkdir_if_missing(dest->buf, 0777);
}
if (S_ISDIR(buf.st_mode)) {
if (de->d_name[0] != '.')
copy_or_link_directory(src, dest,
src_repo, src_baselen);
continue; continue;
} }
/* Files that cannot be copied bit-for-bit... */ /* Files that cannot be copied bit-for-bit... */
if (!strcmp(src->buf + src_baselen, "/info/alternates")) { if (!fspathcmp(iter->relative_path, "info/alternates")) {
copy_alternates(src, dest, src_repo); copy_alternates(src, src_repo);
continue; continue;
} }
if (unlink(dest->buf) && errno != ENOENT) if (unlink(dest->buf) && errno != ENOENT)
die_errno(_("failed to unlink '%s'"), dest->buf); die_errno(_("failed to unlink '%s'"), dest->buf);
if (!option_no_hardlinks) { if (!option_no_hardlinks) {
if (!link(src->buf, dest->buf)) if (!link(real_path(src->buf), dest->buf))
continue; continue;
if (option_local > 0) if (option_local > 0)
die_errno(_("failed to create link '%s'"), dest->buf); die_errno(_("failed to create link '%s'"), dest->buf);
@ -452,7 +461,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
if (copy_file_with_time(dest->buf, src->buf, 0666)) if (copy_file_with_time(dest->buf, src->buf, 0666))
die_errno(_("failed to copy file to '%s'"), dest->buf); die_errno(_("failed to copy file to '%s'"), dest->buf);
} }
closedir(dir);
if (iter_status != ITER_DONE) {
strbuf_setlen(src, src_len);
die(_("failed to iterate over '%s'"), src->buf);
}
} }
static void clone_local(const char *src_repo, const char *dest_repo) static void clone_local(const char *src_repo, const char *dest_repo)
@ -470,7 +483,7 @@ static void clone_local(const char *src_repo, const char *dest_repo)
get_common_dir(&dest, dest_repo); get_common_dir(&dest, dest_repo);
strbuf_addstr(&src, "/objects"); strbuf_addstr(&src, "/objects");
strbuf_addstr(&dest, "/objects"); strbuf_addstr(&dest, "/objects");
copy_or_link_directory(&src, &dest, src_repo, src.len); copy_or_link_directory(&src, &dest, src_repo);
strbuf_release(&src); strbuf_release(&src);
strbuf_release(&dest); strbuf_release(&dest);
} }
@ -492,7 +505,7 @@ static enum {
static const char junk_leave_repo_msg[] = static const char junk_leave_repo_msg[] =
N_("Clone succeeded, but checkout failed.\n" N_("Clone succeeded, but checkout failed.\n"
"You can inspect what was checked out with 'git status'\n" "You can inspect what was checked out with 'git status'\n"
"and retry the checkout with 'git checkout -f HEAD'\n"); "and retry with 'git restore --source=HEAD :/'\n");
static void remove_junk(void) static void remove_junk(void)
{ {
@ -791,6 +804,11 @@ static int checkout(int submodule_progress)
if (option_verbosity < 0) if (option_verbosity < 0)
argv_array_push(&args, "--quiet"); argv_array_push(&args, "--quiet");
if (option_remote_submodules) {
argv_array_push(&args, "--remote");
argv_array_push(&args, "--no-fetch");
}
err = run_command_v_opt(args.argv, RUN_GIT_CMD); err = run_command_v_opt(args.argv, RUN_GIT_CMD);
argv_array_clear(&args); argv_array_clear(&args);
} }
@ -1220,7 +1238,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
remote_head_points_at, &branch_top); remote_head_points_at, &branch_top);
if (filter_options.choice) if (filter_options.choice)
partial_clone_register("origin", &filter_options); partial_clone_register(option_origin, &filter_options);
if (is_local) if (is_local)
clone_local(path, git_dir); clone_local(path, git_dir);
@ -1245,7 +1263,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_disconnect(transport); transport_disconnect(transport);
if (option_dissociate) { if (option_dissociate) {
close_all_packs(the_repository->objects); close_object_store(the_repository->objects);
dissociate_from_references(); dissociate_from_references();
} }

View File

@ -43,7 +43,7 @@ int cmd_column(int argc, const char **argv, const char *prefix)
memset(&copts, 0, sizeof(copts)); memset(&copts, 0, sizeof(copts));
copts.padding = 1; copts.padding = 1;
argc = parse_options(argc, argv, "", options, builtin_column_usage, 0); argc = parse_options(argc, argv, prefix, options, builtin_column_usage, 0);
if (argc) if (argc)
usage_with_options(builtin_column_usage, options); usage_with_options(builtin_column_usage, options);
if (real_command || command) { if (real_command || command) {

View File

@ -5,17 +5,18 @@
#include "parse-options.h" #include "parse-options.h"
#include "repository.h" #include "repository.h"
#include "commit-graph.h" #include "commit-graph.h"
#include "object-store.h"
static char const * const builtin_commit_graph_usage[] = { static char const * const builtin_commit_graph_usage[] = {
N_("git commit-graph [--object-dir <objdir>]"), N_("git commit-graph [--object-dir <objdir>]"),
N_("git commit-graph read [--object-dir <objdir>]"), N_("git commit-graph read [--object-dir <objdir>]"),
N_("git commit-graph verify [--object-dir <objdir>]"), N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"), N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
NULL NULL
}; };
static const char * const builtin_commit_graph_verify_usage[] = { static const char * const builtin_commit_graph_verify_usage[] = {
N_("git commit-graph verify [--object-dir <objdir>]"), N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
NULL NULL
}; };
@ -25,7 +26,7 @@ static const char * const builtin_commit_graph_read_usage[] = {
}; };
static const char * const builtin_commit_graph_write_usage[] = { static const char * const builtin_commit_graph_write_usage[] = {
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"), N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
NULL NULL
}; };
@ -35,9 +36,10 @@ static struct opts_commit_graph {
int stdin_packs; int stdin_packs;
int stdin_commits; int stdin_commits;
int append; int append;
int split;
int shallow;
} opts; } opts;
static int graph_verify(int argc, const char **argv) static int graph_verify(int argc, const char **argv)
{ {
struct commit_graph *graph = NULL; struct commit_graph *graph = NULL;
@ -45,11 +47,14 @@ static int graph_verify(int argc, const char **argv)
int open_ok; int open_ok;
int fd; int fd;
struct stat st; struct stat st;
int flags = 0;
static struct option builtin_commit_graph_verify_options[] = { static struct option builtin_commit_graph_verify_options[] = {
OPT_STRING(0, "object-dir", &opts.obj_dir, OPT_STRING(0, "object-dir", &opts.obj_dir,
N_("dir"), N_("dir"),
N_("The object directory to store the graph")), N_("The object directory to store the graph")),
OPT_BOOL(0, "shallow", &opts.shallow,
N_("if the commit-graph is split, only verify the tip file")),
OPT_END(), OPT_END(),
}; };
@ -59,21 +64,27 @@ static int graph_verify(int argc, const char **argv)
if (!opts.obj_dir) if (!opts.obj_dir)
opts.obj_dir = get_object_directory(); opts.obj_dir = get_object_directory();
if (opts.shallow)
flags |= COMMIT_GRAPH_VERIFY_SHALLOW;
graph_name = get_commit_graph_filename(opts.obj_dir); graph_name = get_commit_graph_filename(opts.obj_dir);
open_ok = open_commit_graph(graph_name, &fd, &st); open_ok = open_commit_graph(graph_name, &fd, &st);
if (!open_ok && errno == ENOENT) if (!open_ok && errno != ENOENT)
return 0;
if (!open_ok)
die_errno(_("Could not open commit-graph '%s'"), graph_name); die_errno(_("Could not open commit-graph '%s'"), graph_name);
graph = load_commit_graph_one_fd_st(fd, &st);
FREE_AND_NULL(graph_name); FREE_AND_NULL(graph_name);
if (open_ok)
graph = load_commit_graph_one_fd_st(fd, &st);
else
graph = read_commit_graph_one(the_repository, opts.obj_dir);
/* Return failure if open_ok predicted success */
if (!graph) if (!graph)
return 1; return !!open_ok;
UNLEAK(graph); UNLEAK(graph);
return verify_commit_graph(the_repository, graph); return verify_commit_graph(the_repository, graph, flags);
} }
static int graph_read(int argc, const char **argv) static int graph_read(int argc, const char **argv)
@ -135,12 +146,15 @@ static int graph_read(int argc, const char **argv)
} }
extern int read_replace_refs; extern int read_replace_refs;
static struct split_commit_graph_opts split_opts;
static int graph_write(int argc, const char **argv) static int graph_write(int argc, const char **argv)
{ {
struct string_list *pack_indexes = NULL; struct string_list *pack_indexes = NULL;
struct string_list *commit_hex = NULL; struct string_list *commit_hex = NULL;
struct string_list lines; struct string_list lines;
int result = 0;
unsigned int flags = COMMIT_GRAPH_PROGRESS;
static struct option builtin_commit_graph_write_options[] = { static struct option builtin_commit_graph_write_options[] = {
OPT_STRING(0, "object-dir", &opts.obj_dir, OPT_STRING(0, "object-dir", &opts.obj_dir,
@ -154,9 +168,21 @@ static int graph_write(int argc, const char **argv)
N_("start walk at commits listed by stdin")), N_("start walk at commits listed by stdin")),
OPT_BOOL(0, "append", &opts.append, OPT_BOOL(0, "append", &opts.append,
N_("include all commits already in the commit-graph file")), N_("include all commits already in the commit-graph file")),
OPT_BOOL(0, "split", &opts.split,
N_("allow writing an incremental commit-graph file")),
OPT_INTEGER(0, "max-commits", &split_opts.max_commits,
N_("maximum number of commits in a non-base split commit-graph")),
OPT_INTEGER(0, "size-multiple", &split_opts.size_multiple,
N_("maximum ratio between two levels of a split commit-graph")),
OPT_EXPIRY_DATE(0, "expire-time", &split_opts.expire_time,
N_("maximum number of commits in a non-base split commit-graph")),
OPT_END(), OPT_END(),
}; };
split_opts.size_multiple = 2;
split_opts.max_commits = 0;
split_opts.expire_time = 0;
argc = parse_options(argc, argv, NULL, argc = parse_options(argc, argv, NULL,
builtin_commit_graph_write_options, builtin_commit_graph_write_options,
builtin_commit_graph_write_usage, 0); builtin_commit_graph_write_usage, 0);
@ -165,11 +191,16 @@ static int graph_write(int argc, const char **argv)
die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs")); die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
if (!opts.obj_dir) if (!opts.obj_dir)
opts.obj_dir = get_object_directory(); opts.obj_dir = get_object_directory();
if (opts.append)
flags |= COMMIT_GRAPH_APPEND;
if (opts.split)
flags |= COMMIT_GRAPH_SPLIT;
read_replace_refs = 0; read_replace_refs = 0;
if (opts.reachable) { if (opts.reachable) {
write_commit_graph_reachable(opts.obj_dir, opts.append, 1); if (write_commit_graph_reachable(opts.obj_dir, flags, &split_opts))
return 1;
return 0; return 0;
} }
@ -188,14 +219,15 @@ static int graph_write(int argc, const char **argv)
UNLEAK(buf); UNLEAK(buf);
} }
write_commit_graph(opts.obj_dir, if (write_commit_graph(opts.obj_dir,
pack_indexes, pack_indexes,
commit_hex, commit_hex,
opts.append, flags,
1); &split_opts))
result = 1;
UNLEAK(lines); UNLEAK(lines);
return 0; return result;
} }
int cmd_commit_graph(int argc, const char **argv, const char *prefix) int cmd_commit_graph(int argc, const char **argv, const char *prefix)

View File

@ -60,15 +60,18 @@ N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\
"\n"); "\n");
static const char empty_cherry_pick_advice_single[] = static const char empty_cherry_pick_advice_single[] =
N_("Otherwise, please use 'git reset'\n"); N_("Otherwise, please use 'git cherry-pick --skip'\n");
static const char empty_cherry_pick_advice_multi[] = static const char empty_cherry_pick_advice_multi[] =
N_("If you wish to skip this commit, use:\n" N_("and then use:\n"
"\n" "\n"
" git reset\n" " git cherry-pick --continue\n"
"\n" "\n"
"Then \"git cherry-pick --continue\" will resume cherry-picking\n" "to resume cherry-picking the remaining commits.\n"
"the remaining commits.\n"); "If you wish to skip this commit, use:\n"
"\n"
" git cherry-pick --skip\n"
"\n");
static const char *color_status_slots[] = { static const char *color_status_slots[] = {
[WT_STATUS_HEADER] = "header", [WT_STATUS_HEADER] = "header",
@ -1078,9 +1081,11 @@ static const char *read_commit_message(const char *name)
static struct status_deferred_config { static struct status_deferred_config {
enum wt_status_format status_format; enum wt_status_format status_format;
int show_branch; int show_branch;
enum ahead_behind_flags ahead_behind;
} status_deferred_config = { } status_deferred_config = {
STATUS_FORMAT_UNSPECIFIED, STATUS_FORMAT_UNSPECIFIED,
-1 /* unspecified */ -1, /* unspecified */
AHEAD_BEHIND_UNSPECIFIED,
}; };
static void finalize_deferred_config(struct wt_status *s) static void finalize_deferred_config(struct wt_status *s)
@ -1107,6 +1112,17 @@ static void finalize_deferred_config(struct wt_status *s)
if (s->show_branch < 0) if (s->show_branch < 0)
s->show_branch = 0; s->show_branch = 0;
/*
* If the user did not give a "--[no]-ahead-behind" command
* line argument *AND* we will print in a human-readable format
* (short, long etc.) then we inherit from the status.aheadbehind
* config setting. In all other cases (and porcelain V[12] formats
* in particular), we inherit _FULL for backwards compatibility.
*/
if (use_deferred_config &&
s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
s->ahead_behind_flags = status_deferred_config.ahead_behind;
if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
s->ahead_behind_flags = AHEAD_BEHIND_FULL; s->ahead_behind_flags = AHEAD_BEHIND_FULL;
} }
@ -1246,6 +1262,10 @@ static int git_status_config(const char *k, const char *v, void *cb)
status_deferred_config.show_branch = git_config_bool(k, v); status_deferred_config.show_branch = git_config_bool(k, v);
return 0; return 0;
} }
if (!strcmp(k, "status.aheadbehind")) {
status_deferred_config.ahead_behind = git_config_bool(k, v);
return 0;
}
if (!strcmp(k, "status.showstash")) { if (!strcmp(k, "status.showstash")) {
s->show_stash = git_config_bool(k, v); s->show_stash = git_config_bool(k, v);
return 0; return 0;
@ -1658,7 +1678,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
die("%s", err.buf); die("%s", err.buf);
} }
sequencer_post_commit_cleanup(the_repository); sequencer_post_commit_cleanup(the_repository, 0);
unlink(git_path_merge_head(the_repository)); unlink(git_path_merge_head(the_repository));
unlink(git_path_merge_msg(the_repository)); unlink(git_path_merge_msg(the_repository));
unlink(git_path_merge_mode(the_repository)); unlink(git_path_merge_mode(the_repository));
@ -1667,10 +1687,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (commit_index_files()) if (commit_index_files())
die(_("repository has been updated, but unable to write\n" die(_("repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full and quota is\n" "new_index file. Check that disk is not full and quota is\n"
"not exceeded, and then \"git reset HEAD\" to recover.")); "not exceeded, and then \"git restore --staged :/\" to recover."));
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0)) if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
write_commit_graph_reachable(get_object_directory(), 0, 0); write_commit_graph_reachable(get_object_directory(), 0, NULL))
return 1;
repo_rerere(the_repository, 0); repo_rerere(the_repository, 0);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD); run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);

Some files were not shown because too many files have changed in this diff Show More