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
# A list of macros that should be interpreted as foreach loops instead of as
# function calls.
ForEachMacros: ['for_each_string_list_item', 'for_each_wanted_builtin', 'for_each_builtin', 'for_each_ut']
# function calls. Taken from:
# 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.
MaxEmptyLinesToKeep: 1

1
.gitattributes vendored
View File

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

11
.gitignore vendored
View File

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

View File

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

View File

@ -195,10 +195,30 @@ For C programs:
by e.g. "echo DEVELOPER=1 >>config.mak".
- 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
initializers, even if a lot of compilers grok it.
including old ones. You should not use features from newer C
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.
@ -412,6 +432,12 @@ For C programs:
must be declared with "extern" in header files. However, function
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:
- 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)))
SP_ARTICLES += $(API_DOCS)
TECH_DOCS += MyFirstContribution
TECH_DOCS += SubmittingPatches
TECH_DOCS += technical/hash-function-transition
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
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::
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
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`:
* Symlinks in `$GIT_DIR` are not resolved before matching.
@ -206,6 +220,11 @@ Example
[includeIf "gitdir:/path/to/group/"]
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
~~~~~~

View File

@ -4,6 +4,10 @@ advice.*::
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::
Set this variable to 'false' if you want to disable
'pushNonFFCurrent',
@ -37,12 +41,19 @@ advice.*::
we can still suggest that the user push to either
refs/heads/* or refs/tags/* based on the type of the
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::
Show directions on how to proceed from the current
state in the output of linkgit:git-status[1], in
the template shown when writing commit messages in
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::
Advise to consider using the `-u` option to linkgit:git-status[1]
when the command takes more than 2 seconds to enumerate untracked
@ -57,17 +68,21 @@ advice.*::
resolveConflict::
Advice shown by various commands when conflicts
prevent the operation from being performed.
sequencerInUse::
Advice shown when a sequencer command is already in progress.
implicitIdentity::
Advice on how to set your identity configuration when
your information is guessed from the system username and
domain name.
detachedHead::
Advice shown when you used linkgit:git-checkout[1] to
move to the detach HEAD state, to instruct how to create
a local branch after the fact.
Advice shown when you used
linkgit:git-switch[1] or linkgit:git-checkout[1]
to move to the detach HEAD state, to instruct how to
create a local branch after the fact.
checkoutAmbiguousRemoteBranchName::
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
situations where an unambiguous argument would have
otherwise caused a remote-tracking branch to be

View File

@ -1,18 +1,28 @@
alias.*::
Command aliases for the linkgit:git[1] command wrapper - e.g.
after defining "alias.last = cat-file commit HEAD", the invocation
"git last" is equivalent to "git cat-file commit HEAD". To avoid
after defining `alias.last = cat-file commit HEAD`, the invocation
`git last` is equivalent to `git cat-file commit HEAD`. To avoid
confusion and troubles with script usage, aliases that
hide existing Git commands are ignored. Arguments are split by
spaces, the usual shell quoting and escaping is supported.
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,
it will be treated as a shell command. For example, defining
"alias.new = !gitk --all --not ORIG_HEAD", the invocation
"git new" is equivalent to running the shell command
"gitk --all --not ORIG_HEAD". Note that shell commands will be
`alias.new = !gitk --all --not ORIG_HEAD`, the invocation
`git new` is equivalent to running the shell command
`gitk --all --not ORIG_HEAD`. Note that shell commands will be
executed from the top-level directory of a repository, which may
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].

View File

@ -19,3 +19,19 @@ blame.showEmail::
blame.showRoot::
Do not treat root commits as boundaries in linkgit:git-blame[1].
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::
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
starting point branch. Note that even if this option is not set,
this behavior can be chosen per-branch using the `--track`
@ -11,7 +11,7 @@ branch.autoSetupMerge::
branch. This option defaults to true.
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
up pull to rebase instead of merge (see "branch.<name>.rebase").
When `never`, rebase is never automatically set to true.

View File

@ -1,5 +1,6 @@
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
tracking e.g. 'origin/<something>'. This stops working as soon
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
`origin`.
+
Currently this is used by linkgit:git-checkout[1] when 'git checkout
<something>' will checkout the '<something>' branch on another remote,
Currently this is used by linkgit:git-switch[1] and
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
remote branch. This setting might be used for other checkout-like
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::
Sets the default value of --ignore-submodules. Note that this
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
'all' disables the submodule summary normally shown by 'git commit'
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.
+
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::
A boolean value which lets you enable the `--base=auto` option of
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
making or verifying a PGP signature. The program must support the
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
code 0, and to generate an ASCII-armored detached signature, the
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
input with a single key (i.e., without hitting enter).
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
setting is silently ignored if portable keystroke input
is not available; requires the Perl module Term::ReadKey.

View File

@ -40,4 +40,5 @@ log.showSignature::
log.mailmap::
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].
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::
If set to true, linkgit:git-status[1] will insert a comment
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
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::
This variable can be used to restrict the permission bits of
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
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::
--prune::
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
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::
--ipv4::
Use IPv4 addresses only, ignoring IPv6 addresses.

View File

@ -10,6 +10,7 @@ SYNOPSIS
[verse]
'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>]
[--ignore-rev <rev>] [--ignore-revs-file <file>]
[--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>..<rev>]
[--] <file>

View File

@ -8,12 +8,14 @@ git-branch - List, create, or delete branches
SYNOPSIS
--------
[verse]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
[--list] [--show-current] [-v [--abbrev=<length> | --no-abbrev]]
'git branch' [--color[=<when>] | --no-color] [--show-current]
[-v [--abbrev=<length> | --no-abbrev]]
[--column[=<options>] | --no-column] [--sort=<key>]
[(--merged | --no-merged) [<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' (--set-upstream-to=<upstream> | -u <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
branches are listed; the current branch will be highlighted with an
asterisk. Option `-r` causes the remote-tracking branches to be listed,
and option `-a` shows both local and remote branches. If a `<pattern>`
branches are listed; the current branch will be highlighted in green and
marked with an asterisk. Any branches checked out in linked worktrees will
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
matching branches. If multiple patterns are given, a branch is shown if
it matches any of the patterns. Note that when providing a
`<pattern>`, you must use `--list`; otherwise the command is interpreted
it matches any of the patterns.
Note that when providing a
`<pattern>`, you must use `--list`; otherwise the command may be interpreted
as branch creation.
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`.
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.
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::
--remotes::
List or delete (if used with -d) the remote-tracking branches.
Combine with `--list` to match the optional pattern(s).
-a::
--all::
List both remote-tracking branches and local branches.
Combine with `--list` to match optional pattern(s).
-l::
--list::
@ -174,8 +184,10 @@ This option is only applicable in non-verbose mode.
When in list mode,
show sha1 and commit subject line for each head, along with
relationship to upstream branch (if any). If given twice, print
the name of the upstream branch, as well (see also `git remote
show <remote>`).
the path of the linked worktree (if any) and the name of the upstream
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::
--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.
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
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
$ cd my2.6
$ 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
@ -322,13 +334,25 @@ $ git branch -D test <2>
<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.
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
-----
If you are creating a branch that you want to checkout immediately, it is
easier to use the git checkout command with its `-b` option to create
a branch and check it out with a single command.
If you are creating a branch that you want to switch to immediately,
it is easier to use the "git switch" command with its `-c` option to
do the same thing with a single command.
The options `--contains`, `--no-contains`, `--merged` and `--no-merged`
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
expanded for the ``previous checkout syntax''
`@{-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
expected, so they can act as if you typed the branch name. As an
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
branch.
'git checkout' <branch>::
To prepare for working on <branch>, switch to it by updating
'git checkout' [<branch>]::
To prepare for working on `<branch>`, switch to it by updating
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
<branch>.
`<branch>`.
+
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
If `<branch>` is not found but there does exist a tracking branch in
exactly one remote (call it `<remote>`) with a matching name and
`--no-guess` is not specified, 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].
+
You could omit <branch>, in which case the command degenerates to
You could omit `<branch>`, in which case the command degenerates to
"check out the current branch", which is a glorified no-op with
rather expensive side-effects to show only the tracking information,
if exists, for the current branch.
@ -61,7 +52,7 @@ if exists, for the current branch.
`--track` without `-b` implies branch creation; see the
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
+
------------
@ -75,25 +66,25 @@ successful.
'git checkout' --detach [<branch>]::
'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
files in the working tree. Local modifications to the files
in the working tree are kept, so that the resulting working
tree will be the state recorded in the commit plus the local
modifications.
+
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
<branch>` would check out that branch without detaching HEAD).
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
<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>...::
Overwrite paths in the working tree by replacing with the
contents in the index or in the <tree-ish> (most often a
commit). When a <tree-ish> is given, the paths that
match the <pathspec> are updated both in the index and in
contents in the index or in the `<tree-ish>` (most often a
commit). When a `<tree-ish>` is given, the paths that
match the `<pathspec>` are updated both in the index and in
the working tree.
+
The index may contain unmerged entries because of a previous failed merge.
@ -118,7 +109,8 @@ OPTIONS
--quiet::
Quiet, suppress feedback messages.
--[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
@ -127,7 +119,7 @@ OPTIONS
-f::
--force::
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.
+
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").
-b <new_branch>::
Create a new branch named <new_branch> and start it at
<start_point>; see linkgit:git-branch[1] for details.
Create a new branch named `<new_branch>` and start it at
`<start_point>`; see linkgit:git-branch[1] for details.
-B <new_branch>::
Creates the branch <new_branch> and start it at <start_point>;
if it already exists, then reset it to <start_point>. This is
Creates the branch `<new_branch>` and start it at `<start_point>`;
if it already exists, then reset it to `<start_point>`. This is
equivalent to running "git branch" with "-f"; see
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
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
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 `-b` in such a case.
--no-track::
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::
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::
Rather than checking out a branch to work on it, check out a
commit for inspection and discardable experiments.
This is the default behavior of "git checkout <commit>" when
<commit> is not a branch name. See the "DETACHED HEAD" section
This is the default behavior of `git checkout <commit>` when
`<commit>` is not a branch name. See the "DETACHED HEAD" section
below for details.
--orphan <new_branch>::
Create a new 'orphan' branch, named <new_branch>, started from
<start_point> and switch to it. The first commit made on this
Create a new 'orphan' branch, named `<new_branch>`, started from
`<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
history totally disconnected from all the other branches and
commits.
+
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
that records a set of paths similar to <start_point> by easily running
"git commit -a" to make the root commit.
`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
`git commit -a` to make the root 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
@ -212,17 +225,17 @@ whose full history contains proprietary or otherwise encumbered bits of
code.
+
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
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
working tree, by copying them from elsewhere, extracting a tarball, etc.
--ignore-skip-worktree-bits::
In sparse checkout mode, `git checkout -- <paths>` would
update only entries matched by <paths> and sparse patterns
in $GIT_DIR/info/sparse-checkout. This option ignores
the sparse patterns and adds back any files in <paths>.
update only entries matched by `<paths>` and sparse patterns
in `$GIT_DIR/info/sparse-checkout`. This option ignores
the sparse patterns and adds back any files in `<paths>`.
-m::
--merge::
@ -246,25 +259,25 @@ the conflicted merge in the specified paths.
When switching branches with `--merge`, staged changes may be lost.
--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
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" style, shows the original contents).
-p::
--patch::
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
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
edits from your current working tree. See the ``Interactive 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
`--[no-]overlay`), and currently doesn't support overlay mode.
`--overlay`), and currently doesn't support overlay mode.
--ignore-other-worktrees::
`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
worktree.
--[no-]recurse-submodules::
Using --recurse-submodules will update the content of all initialized
--overwrite-ignore::
--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
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.
Just like linkgit:git-submodule[1], this will detach the
submodules HEAD.
Just like linkgit:git-submodule[1], this will detach `HEAD` of the
submodule.
--no-guess::
Do not attempt to create a branch if a remote tracking branch
of the same name exists.
--[no-]overlay::
--overlay::
--no-overlay::
In the default overlay mode, `git checkout` never
removes files from the index or the working tree. When
specifying `--no-overlay`, files that appear in the index and
working tree, but not in <tree-ish> are removed, to make them
match <tree-ish> exactly.
working tree, but not in `<tree-ish>` are removed, to make them
match `<tree-ish>` exactly.
<branch>::
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
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).
+
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
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
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>::
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
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
-------------
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
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')
@ -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
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
commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers
to commit 'd':
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
commit `d`. `HEAD` still refers to branch `master` and so indirectly now refers
to commit `d`:
------------
$ 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
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
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
@ -376,9 +393,9 @@ a---b---c---d branch 'master' (refers to commit 'd')
tag 'v2.0' (refers to commit 'b')
------------
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.
It means simply that HEAD refers to a specific commit, as opposed to
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.
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:
------------
@ -395,7 +412,7 @@ a---b---c---d branch 'master' (refers to commit 'd')
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:
------------
@ -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
at what happens when we then checkout master:
at what happens when we then 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
'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
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:
------------
@ -439,19 +456,19 @@ $ git branch foo <2>
$ git tag foo <3>
------------
<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
be in detached HEAD state after this command.
<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
be in detached `HEAD` state after this command.
<2> similarly creates a new branch 'foo', which refers to commit 'f',
but leaves HEAD detached.
<2> similarly creates a new branch `foo`, which refers to commit `f`,
but leaves `HEAD` detached.
<3> creates a new tag 'foo', which refers to commit 'f',
leaving HEAD detached.
<3> creates a new tag `foo`, which refers to commit `f`,
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
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:
------------
@ -462,12 +479,12 @@ $ git log -g -2 HEAD
ARGUMENT DISAMBIGUATION
-----------------------
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>`
(e.g. a branch "abc" exists) and a valid `<pathspec>` (e.g. a file
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>`
(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
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
to checkout these paths out of the index.
@ -475,7 +492,7 @@ EXAMPLES
--------
. 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.
+
------------
@ -487,7 +504,7 @@ $ git checkout hello.c <3>
+
<1> switch branch
<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,
you can say
@ -516,7 +533,7 @@ $ git checkout -- hello.c
$ 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
the above checkout would fail like this:
+
@ -557,6 +574,11 @@ $ edit frotz
$ git add frotz
------------
SEE ALSO
--------
linkgit:git-switch[1],
linkgit:git-restore[1]
GIT
---
Part of the linkgit:git[1] suite

View File

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

View File

@ -63,7 +63,7 @@ OPTIONS
still use the ignore rules given with `-e` options from the command
line. This allows removing all untracked
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.
-X::

View File

@ -15,14 +15,15 @@ SYNOPSIS
[--dissociate] [--separate-git-dir <git dir>]
[--depth <depth>] [--[no-]single-branch] [--no-tags]
[--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
[--jobs <n>] [--] <repository> [<directory>]
[--[no-]remote-submodules] [--jobs <n>] [--] <repository>
[<directory>]
DESCRIPTION
-----------
Clones a repository into a newly created directory, creates
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
currently active branch.
@ -40,8 +41,8 @@ configuration variables.
OPTIONS
-------
--local::
-l::
--local::
When the repository to clone from is on a local machine,
this flag bypasses the normal "Git aware" transport
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
if you are trying to make a back-up of your repository.
--shared::
-s::
--shared::
When the repository to clone is on the local machine,
instead of using hard links, automatically setup
`.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,
then the cloned repository will become corrupt.
+
Note that running `git repack` without the `-l` option in a repository
cloned with `-s` will copy objects from the source repository into a pack
in the cloned repository, removing the disk space savings of `clone -s`.
It is safe, however, to run `git gc`, which uses the `-l` option by
Note that running `git repack` without the `--local` option in a repository
cloned with `--shared` will copy objects from the source repository into a pack
in the cloned repository, removing the disk space savings of `clone --shared`.
It is safe, however, to run `git gc`, which uses the `--local` option by
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
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
borrowing.
--quiet::
-q::
--quiet::
Operate quietly. Progress is not reported to the standard
error stream.
--verbose::
-v::
--verbose::
Run verbosely. Does not affect the reporting of progress status
to the standard error stream.
--progress::
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
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
sent to the other side in the order listed on the command line.
--no-checkout::
-n::
--no-checkout::
No checkout of HEAD is performed after the clone is complete.
--bare::
Make a 'bare' Git repository. That is, instead of
creating `<directory>` and placing the administrative
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.
Also the branch heads at the remote are copied directly
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
target repository.
--origin <name>::
-o <name>::
--origin <name>::
Instead of using the remote name `origin` to keep track
of the upstream repository, use `<name>`.
--branch <name>::
-b <name>::
--branch <name>::
Instead of pointing the newly created HEAD to the branch pointed
to by the cloned repository's HEAD, point to `<name>` branch
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
in the resulting repository.
--upload-pack <upload-pack>::
-u <upload-pack>::
--upload-pack <upload-pack>::
When given, and the repository to clone from is accessed
via ssh, this specifies a non-default path for the command
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;
(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
--config <key>=<value>::
-c <key>=<value>::
--config <key>=<value>::
Set a configuration variable in the newly-created repository;
this takes effect immediately after the repository is
initialized, but before the remote history is fetched or any
@ -260,6 +261,12 @@ or `--mirror` is given)
--[no-]shallow-submodules::
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>::
Instead of placing the cloned repository where it is supposed
to be, place the cloned repository at the specified directory,

View File

@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'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>]
@ -26,7 +26,7 @@ OPTIONS
Use given directory for the location of packfiles and commit-graph
file. This parameter exists to specify the location of an alternate
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`.
@ -51,6 +51,25 @@ or `--stdin-packs`.)
+
With the `--append` option, include all commits that are present in the
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'::
@ -61,6 +80,9 @@ Used for debugging purposes.
Read the commit-graph file and verify its contents against the object
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

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
called the "index" with 'git add'. A file can be
reverted back, only in the index but not in the working tree,
to that of the last commit with `git reset HEAD -- <file>`,
to that of the last commit with `git restore --staged <file>`,
which effectively reverts 'git add' and prevents the changes to
this file from participating in the next commit. After building
the state to be committed incrementally with these commands,

View File

@ -129,6 +129,13 @@ marks the same across runs.
for intermediary filters (e.g. for rewriting commit messages
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::
Apply the specified refspec to each ref exported. Multiple of them can
be specified.

View File

@ -388,6 +388,7 @@ change to the project.
original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
('encoding' SP <encoding>)?
data
('from' 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
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`
^^^^^^
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`
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
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
be used to specify the value in the header field.

View File

@ -22,7 +22,8 @@ SYNOPSIS
[--rfc] [--subject-prefix=Subject-Prefix]
[(--reroll-count|-v) <n>]
[--to=<email>] [--cc=<email>]
[--[no-]cover-letter] [--quiet] [--notes[=<ref>]]
[--[no-]cover-letter] [--quiet]
[--no-notes | --notes[=<ref>]]
[--interdiff=<previous>]
[--range-diff=<previous> [--creation-factor=<percent>]]
[--progress]
@ -263,6 +264,7 @@ material (this may change in the future).
for details.
--notes[=<ref>]::
--no-notes::
Append the notes (see linkgit:git-notes[1]) for the commit
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
of the patch series (but see the discussion of the `notes.rewrite`
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>::
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:
$ git fetch <project> master:test-apply
$ git checkout test-apply
$ git reset --hard
$ git switch test-apply
$ git restore --source=HEAD --staged --worktree :/
$ git am a.patch
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
work tree), and optionally writes the resulting object into the
object database. Reports its object ID to its standard output.
This is used by 'git cvsimport' to update the index
without modifying files in the work tree. When <type> is not
specified, it defaults to "blob".
When <type> is not specified, it defaults to "blob".
OPTIONS
-------

View File

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

View File

@ -149,7 +149,7 @@ instead.
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
`origin/master` may have been rewound and rebuilt, leading to a
history of this shape:

View File

@ -13,8 +13,7 @@ SYNOPSIS
[-s <strategy>] [-X <strategy-option>] [-S[<keyid>]]
[--[no-]allow-unrelated-histories]
[--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>...]
'git merge' --abort
'git merge' --continue
'git merge' (--continue | --abort | --quit)
DESCRIPTION
-----------
@ -88,6 +87,11 @@ will be appended to the specified message.
Allow the rerere mechanism to update the index with the
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 the current conflict resolution process, and
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
`MERGE_HEAD` is present.
--quit::
Forget about the current merge in progress. Leave the index
and the working tree as-is.
--continue::
After a 'git merge' stops due to conflicts you can conclude the
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
--------
[verse]
'git multi-pack-index' [--object-dir=<dir>] <verb>
'git multi-pack-index' [--object-dir=<dir>] <subcommand>
DESCRIPTION
-----------
@ -23,13 +23,35 @@ OPTIONS
`<dir>/packs/multi-pack-index` for the current MIDX file, and
`<dir>/packs` for the pack-files to index.
The following subcommands are available:
write::
When given as the verb, write a new MIDX file to
`<dir>/packs/multi-pack-index`.
Write a new MIDX file.
verify::
When given as the verb, verify the contents of the MIDX file
at `<dir>/packs/multi-pack-index`.
Verify the contents of the MIDX file.
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

View File

@ -12,12 +12,12 @@ SYNOPSIS
[<upstream> [<branch>]]
'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
--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
-----------
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.
If <upstream> is not specified, the upstream configured in

View File

@ -230,7 +230,7 @@ $ git branch -r
staging/master
staging/staging-linus
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:
------------
$ git checkout topic
$ git switch topic
$ git merge master
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:
------------
$ git checkout topic
$ git switch topic
$ git merge master
$ ... work on both topic and master branches
$ git checkout master
$ git switch master
$ git merge 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:
------------
$ git checkout topic
$ git switch topic
$ git merge master
$ git reset --hard HEAD^ ;# rewind the test merge
$ ... work on both topic and master branches
$ git checkout master
$ git switch master
$ git merge 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.)
+
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
use linkgit:git-checkout[1] to check the contents out of the index to
the working tree.
Alternatively, using linkgit:git-checkout[1] and specifying a commit, you
use linkgit:git-restore[1] to check the contents out of the index to
the working tree. Alternatively, using linkgit:git-restore[1]
and specifying a commit with `--source`, you
can copy the contents of a path out of a commit to the index and to the
working tree in one go.
@ -86,8 +87,8 @@ but carries forward unmerged index entries.
changes, reset is aborted.
--
If you want to undo a commit other than the latest on a branch,
linkgit:git-revert[1] is your friend.
See "Reset, restore and revert" in linkgit:git[1] for the differences
between the three commands.
OPTIONS
@ -149,9 +150,9 @@ See also the `--amend` option to linkgit:git-commit[1].
Undo a commit, making it a topic branch::
+
------------
$ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2>
$ git checkout topic/wip <3>
$ git branch topic/wip <1>
$ git reset --hard HEAD~3 <2>
$ git switch topic/wip <3>
------------
+
<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.
+
------------
$ git checkout feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted
$ git switch feature ;# you were working in "feature" branch and
$ work work work ;# got interrupted
$ git commit -a -m "snapshot WIP" <1>
$ git checkout master
$ git switch master
$ fix fix fix
$ git commit ;# commit with real log
$ git checkout feature
$ git switch feature
$ git reset --soft HEAD^ ;# go back to WIP state <2>
$ git reset <3>
------------
@ -279,18 +280,18 @@ reset it while keeping the changes in your working tree.
+
------------
$ git tag start
$ git checkout -b branch1
$ git switch -c branch1
$ edit
$ git commit ... <1>
$ edit
$ git checkout -b branch2 <2>
$ git switch -c branch2 <2>
$ git reset --keep start <3>
------------
+
<1> This commits your first edits in `branch1`.
<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
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.
<3> But you can use `reset --keep` to remove the unwanted commit after
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>]
[ [ --objects | --objects-edge | --objects-edge-aggressive ]
[ --unpacked ]
[ --object-names | --no-object-names ]
[ --filter=<filter-spec> [ --filter-print-omitted ] ] ]
[ --missing=<missing-action> ]
[ --pretty | --header ]

View File

@ -9,9 +9,7 @@ SYNOPSIS
--------
[verse]
'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>...
'git revert' --continue
'git revert' --quit
'git revert' --abort
'git revert' (--continue | --skip | --abort | --quit)
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
should see linkgit:git-reset[1], particularly the `--hard` option. If
you want to extract specific files as they were in another commit, you
should see linkgit:git-checkout[1], specifically the `git checkout
<commit> -- <filename>` syntax. Take care with these alternatives as
should see linkgit:git-restore[1], specifically the `--source`
option. Take care with these alternatives as
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
-------
<commit>...::

View File

@ -278,6 +278,14 @@ must be used for each option.
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>::
Specify a command to execute once per patch file which
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
the credential store so you won't have to type it the next time.
Note: the following perl modules are required
Net::SMTP::SSL, MIME::Base64 and Authen::SASL
Note: the following core Perl modules that may be installed with your
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
--------

View File

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

View File

@ -9,7 +9,7 @@ git-update-server-info - Update auxiliary info file to help dumb servers
SYNOPSIS
--------
[verse]
'git update-server-info' [--force]
'git update-server-info'
DESCRIPTION
-----------
@ -19,15 +19,6 @@ $GIT_OBJECT_DIRECTORY/info directories to help clients discover
what references and packs the server has. This command
generates such auxiliary files.
OPTIONS
-------
-f::
--force::
Update the info files from scratch.
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.
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
@ -56,7 +57,8 @@ help ...`.
Run as if git was started in '<path>' instead of the current working
directory. When multiple `-C` options are given, each subsequent
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
`--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[]
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)
-----------------------------

View File

@ -112,7 +112,8 @@ Checking-out and checking-in
These attributes affect how the contents stored in the
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
repository upon 'git add' and 'git commit'.
@ -819,7 +820,7 @@ patterns are available:
- `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.
@ -833,6 +834,8 @@ patterns are available:
- `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.

View File

@ -47,8 +47,8 @@ disambiguating `--` at appropriate places.
things:
+
--------------------------------
$ git checkout -- *.c
$ git checkout -- \*.c
$ git restore *.c
$ git restore \*.c
--------------------------------
+
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
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
---
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:
------------
$ git checkout -b mybranch
$ git switch -c mybranch
------------
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
------------
$ git checkout -b mybranch earlier-commit
$ git switch -c mybranch 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
------------
$ git checkout master
$ git switch master
------------
(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.
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.
@ -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.
------------------------------------------------
$ git checkout mybranch
$ git switch mybranch
$ echo "Work, work, work" >>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:
------------
$ git checkout master
$ git switch master
------------
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 checkout mybranch
$ git switch mybranch
$ git merge -m "Merge upstream changes." master
------------
@ -1133,9 +1133,8 @@ Remember, before running 'git merge', our `master` head was at
work." commit.
------------
$ git checkout mybranch
$ git reset --hard master^2
$ git checkout master
$ git switch -C mybranch master^2
$ git switch master
$ git reset --hard master^
------------

View File

@ -41,7 +41,7 @@ following commands.
* 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.
* 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-reset[1] and linkgit:git-checkout[1] (with
pathname parameters) to undo changes.
* linkgit:git-restore[1] to undo changes.
* linkgit:git-merge[1] to merge between local branches.
@ -80,9 +79,9 @@ $ git tag v2.43 <2>
Create a topic branch and develop.::
+
------------
$ git checkout -b alsa-audio <1>
$ git switch -c alsa-audio <1>
$ 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>
$ edit/compile/test
$ git diff HEAD <4>
@ -90,7 +89,7 @@ $ git commit -a -s <5>
$ edit/compile/test
$ git diff HEAD^ <6>
$ git commit -a --amend <7>
$ git checkout master <8>
$ git switch master <8>
$ git merge alsa-audio <9>
$ git log --since='3 days ago' <10>
$ 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
$ cd my2.6
$ git checkout -b mine master <1>
$ git switch -c mine master <1>
$ edit/compile/test; git commit -a -s <2>
$ git format-patch master <3>
$ git send-email --to="person <email@example.com>" 00*.patch <4>
$ git checkout master <5>
$ git switch master <5>
$ git pull <6>
$ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <7>
$ 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>
mothership$ cd frotz
mothership$ git checkout master
mothership$ git switch master
mothership$ git merge satellite/master <5>
------------
+
@ -216,7 +215,7 @@ machine into the master branch.
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
$ git checkout master
$ git cherry-pick v2.6.14..private2.6.14 <2>
@ -274,14 +273,14 @@ $ mailx <3>
& s 2 3 4 5 ./+to-apply
& s 7 8 ./+hold-linus
& q
$ git checkout -b topic/one master
$ git switch -c topic/one master
$ git am -3 -i -s ./+to-apply <4>
$ compile/test
$ git checkout -b hold/linus && git am -3 -i -s ./+hold-linus <5>
$ git checkout topic/one && git rebase master <6>
$ git checkout pu && git reset --hard next <7>
$ git switch -c hold/linus && git am -3 -i -s ./+hold-linus <5>
$ git switch topic/one && git rebase master <6>
$ git switch -C pu next <7>
$ git merge topic/one topic/two && git merge hold/linus <8>
$ git checkout maint
$ git switch maint
$ git cherry-pick master~4 <9>
$ compile/test
$ 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
~~~~~~~~~~~~~
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,
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,
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
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"`
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
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
with the difference between the branches.

View File

@ -89,28 +89,28 @@ PATTERN FORMAT
Put a backslash ("`\`") in front of the first "`!`" for patterns
that begin with a literal "`!`", for example, "`\!important!.txt`".
- If the pattern ends with a slash, it is removed for the
purpose of the following description, but it would only find
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).
- The slash '/' is used as the directory separator. Separators may
occur at the beginning, middle or end of the `.gitignore` search pattern.
- If the pattern does not contain a slash '/', Git treats it as
a shell glob pattern and checks for a match against the
pathname relative to the location of the `.gitignore` file
(relative to the toplevel of the work tree if not from a
`.gitignore` file).
- If there is a separator at the beginning or middle (or both) of the
pattern, then the pattern is relative to the directory level of the
particular `.gitignore` file itself. Otherwise the pattern may also
match at any level below the `.gitignore` level.
- Otherwise, Git treats the pattern as a shell glob: "`*`" matches
anything except "`/`", "`?`" matches any one character except "`/`"
and "`[]`" matches one character in a selected range. See
fnmatch(3) and the FNM_PATHNAME flag for a more detailed
description.
- If there is a separator at the end of the pattern then the pattern
will only match directories, otherwise the pattern can match both
files and directories.
- A leading slash matches the beginning of the pathname.
For example, "/{asterisk}.c" matches "cat-file.c" but not
"mozilla-sha1/sha1.c".
- For example, a pattern `doc/frotz/` matches `doc/frotz` directory,
but not `a/doc/frotz` directory; however `frotz/` matches `frotz`
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
full pathname may have special meaning:
@ -152,6 +152,28 @@ To stop tracking a file that is currently tracked, use
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
[...]

View File

@ -370,13 +370,13 @@ situation:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
(use "git restore --staged <file>..." to unstage)
new file: closing.txt
Changes not staged for commit:
(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

View File

@ -110,7 +110,7 @@ $ git status
On branch master
Changes to be committed:
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: file2
@ -207,7 +207,7 @@ automatically. The asterisk marks the branch you are currently on;
type
------------------------------------------------
$ git checkout experimental
$ git switch experimental
------------------------------------------------
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)
$ git commit -a
$ git checkout master
$ git switch master
------------------------------------------------
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.
* Finding commits which commit messages matches given search term.
See http://git.kernel.org/?p=git/git.git;a=tree;f=gitweb[] or
http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
See http://repo.or.cz/w/git.git/tree/HEAD:/gitweb/[] for gitweb source code,
browsed using gitweb itself.

View File

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

View File

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

View File

@ -182,6 +182,14 @@ explicitly.
Pretend as if all objects mentioned by reflogs are listed on the
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::
By default, all working trees will be examined by the
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
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>::
Only useful with one of the `--objects*`; omits objects (usually
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 remote.pushdefault myfork
$ git checkout -b mybranch origin/master
$ git switch -c mybranch origin/master
$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master

View File

@ -3,6 +3,10 @@
`.git/sequencer`. Can be used to continue after resolving
conflicts in a failed cherry-pick or revert.
--skip::
Skip the current commit and continue with the rest of the
sequence.
--quit::
Forget about the current operation in progress. Can be used
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 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
config setting.
@ -668,7 +668,7 @@ completed.)
"event":"signal",
...
"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 (reserved for later use)
Current clients should ignore this value.
1-byte number (B) of base commit-graphs
We infer the length (H*B) of the Base Graphs chunk
from this value.
CHUNK LOOKUP:
@ -92,6 +93,12 @@ CHUNK DATA:
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.
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:
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
written when shallow commits are present.
Future Work
-----------
Commit Graphs Chains
--------------------
- After computing and storing generation numbers, we must make graph
walks aware of generation numbers to gain the performance benefits they
enable. This will mostly be accomplished by swapping a commit-date-ordered
priority queue with one ordered by generation number. The following
operations are important candidates:
Typically, repos grow with near-constant velocity (commits per day). Over time,
the number of commits added by a fetch operation is much smaller than the
number of commits in the full history. By creating a "chain" of commit-graphs,
we enable fast writes of new commit data without rewriting the entire commit
history -- at least, most of the time.
- 'log --topo-order'
- 'tag --merged'
## File Layout
- A server could provide a commit-graph file as part of the network protocol
to avoid extra calculations by clients. This feature is only of benefit if
the user is willing to trust the file, because verifying the file is correct
is as hard as computing it from scratch.
A commit-graph chain uses multiple files, and we use a fixed naming convention
to organize these files. Each commit-graph file has a name
`$OBJDIR/info/commit-graphs/graph-{hash}.graph` where `{hash}` is the hex-
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
-------------
@ -170,3 +344,7 @@ Related Links
[4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u
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.
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
@ -282,10 +282,10 @@ a summary of the commands:
this command will fail with a warning.
`git branch -D <branch>`::
delete the branch `<branch>` irrespective of its merged status.
`git checkout <branch>`::
`git switch <branch>`::
make the current branch `<branch>`, updating the working
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
check it out.
@ -302,22 +302,22 @@ ref: refs/heads/master
Examining an old version without creating a new branch
------------------------------------------------------
The `git checkout` command normally expects a branch head, but will also
accept an arbitrary commit; for example, you can check out the commit
referenced by a tag:
The `git switch` command normally expects a branch head, but will also
accept an arbitrary commit when invoked with --detach; for example,
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'.
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
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
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
------------------------------------------------
@ -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:
------------------------------------------------
$ 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
@ -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
-------------------------------------------------
$ git reset --hard HEAD
$ git merge --abort
-------------------------------------------------
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
-------------------------------------------------
$ git reset --hard HEAD
$ git restore --staged --worktree :/
-------------------------------------------------
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
useful to check out an older version of a particular file using
linkgit:git-checkout[1]. We've used `git checkout` before to switch
branches, but it has quite different behavior if it is given a path
name: the command
linkgit:git-restore[1]. 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
@ -2211,8 +2209,8 @@ $ git branch --track release origin/master
These can be easily kept up to date using linkgit:git-pull[1].
-------------------------------------------------
$ git checkout test && git pull
$ git checkout release && git pull
$ git switch test && git pull
$ git switch release && git pull
-------------------------------------------------
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
-------------------------------------------------
$ 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
@ -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:
-------------------------------------------------
$ 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
@ -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.
-------------------------------------------------
$ 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
@ -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:
-------------------------------------------------
$ git checkout -b mywork origin
$ git switch -c mywork origin
$ vi file.txt
$ git commit
$ vi otherfile.txt
@ -2552,7 +2550,7 @@ commits without any merges, you may instead choose to use
linkgit:git-rebase[1]:
-------------------------------------------------
$ git checkout mywork
$ git switch mywork
$ git rebase origin
-------------------------------------------------
@ -3668,13 +3666,13 @@ change within the submodule, and then update the superproject to reference the
new commit:
-------------------------------------------------
$ git checkout master
$ git switch master
-------------------------------------------------
or
-------------------------------------------------
$ git checkout -b fix-up
$ git switch -c fix-up
-------------------------------------------------
then
@ -3800,8 +3798,8 @@ use linkgit:git-tag[1] for both.
The Workflow
------------
High-level operations such as linkgit:git-commit[1],
linkgit:git-checkout[1] and linkgit:git-reset[1] work by moving data
High-level operations such as linkgit:git-commit[1] and
linkgit:git-restore[1] work by moving data
between the working tree, the index, and the object database. Git
provides low-level operations which perform each of these steps
individually.
@ -4194,7 +4192,7 @@ start.
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
@ -4437,10 +4435,10 @@ Managing branches
-----------------
-----------------------------------------------
$ git branch # list all local branches in this repo
$ git checkout test # switch working directory to branch "test"
$ git branch new # create branch "new" starting at current HEAD
$ git branch -d new # delete branch "new"
$ git branch # list all local branches in this repo
$ git switch test # switch working directory to branch "test"
$ git branch new # create branch "new" starting at current HEAD
$ git branch -d new # delete branch "new"
-----------------------------------------------
Instead of basing a new branch on current HEAD (the default), use:
@ -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:
-----------------------------------------------
$ git checkout -b new v2.6.15
$ git switch -c new v2.6.15
-----------------------------------------------
Update and examine branches from the repository you cloned from:
@ -4467,7 +4465,7 @@ $ git branch -r # list
origin/master
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

View File

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

View File

@ -265,10 +265,6 @@ all::
#
# 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,
# 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-parse-remote
SCRIPT_LIB += git-rebase--am
SCRIPT_LIB += git-rebase--common
SCRIPT_LIB += git-rebase--preserve-merges
SCRIPT_LIB += git-sh-setup
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-date.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-dump-cache-tree.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-mergesort.o
TEST_BUILTINS_OBJS += test-mktemp.o
TEST_BUILTINS_OBJS += test-oidmap.o
TEST_BUILTINS_OBJS += test-online-cpus.o
TEST_BUILTINS_OBJS += test-parse-options.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-init$X
BUILT_INS += git-merge-subtree$X
BUILT_INS += git-restore$X
BUILT_INS += git-show$X
BUILT_INS += git-stage$X
BUILT_INS += git-status$X
BUILT_INS += git-switch$X
BUILT_INS += git-whatchanged$X
# 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.o
BUILTIN_OBJS += builtin/difftool.o
BUILTIN_OBJS += builtin/env--helper.o
BUILTIN_OBJS += builtin/fast-export.o
BUILTIN_OBJS += builtin/fetch-pack.o
BUILTIN_OBJS += builtin/fetch.o
@ -1160,6 +1159,7 @@ endif
# which'll override these defaults.
CFLAGS = -g -O2 -Wall
LDFLAGS =
CC_LD_DYNPATH = -Wl,-rpath,
BASIC_CFLAGS = -I.
BASIC_LDFLAGS =
@ -1240,7 +1240,7 @@ endif
ifdef 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}
else
BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d'
@ -1290,16 +1290,6 @@ ifeq ($(uname_S),Darwin)
PTHREAD_LIBS =
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
COMPAT_CFLAGS += -DNO_LIBGEN_H
COMPAT_OBJS += compat/basename.o
@ -2873,6 +2863,33 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_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
$(INSTALL) -d -m 755 '$(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-USER-AGENT GIT-PREFIX
$(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: 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
[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
read with `man gittutorial` or `git help tutorial`, and the
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 "help.h"
int advice_fetch_show_forced_updates = 1;
int advice_push_update_rejected = 1;
int advice_push_non_ff_current = 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_status_hints = 1;
int advice_status_u_option = 1;
int advice_status_ahead_behind_warning = 1;
int advice_commit_before_merge = 1;
int advice_reset_quiet_warning = 1;
int advice_resolve_conflict = 1;
int advice_sequencer_in_use = 1;
int advice_implicit_identity = 1;
int advice_detached_head = 1;
int advice_set_upstream_failure = 1;
@ -59,6 +62,7 @@ static struct {
const char *name;
int *preference;
} advice_config[] = {
{ "fetchShowForcedUpdates", &advice_fetch_show_forced_updates },
{ "pushUpdateRejected", &advice_push_update_rejected },
{ "pushNonFFCurrent", &advice_push_non_ff_current },
{ "pushNonFFMatching", &advice_push_non_ff_matching },
@ -68,9 +72,11 @@ static struct {
{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
{ "statusHints", &advice_status_hints },
{ "statusUoption", &advice_status_u_option },
{ "statusAheadBehindWarning", &advice_status_ahead_behind_warning },
{ "commitBeforeMerge", &advice_commit_before_merge },
{ "resetQuiet", &advice_reset_quiet_warning },
{ "resolveConflict", &advice_resolve_conflict },
{ "sequencerInUse", &advice_sequencer_in_use },
{ "implicitIdentity", &advice_implicit_identity },
{ "detachedHead", &advice_detached_head },
{ "setupStreamFailure", &advice_set_upstream_failure },
@ -193,13 +199,22 @@ void NORETURN die_conclude_merge(void)
void detach_advice(const char *new_name)
{
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"
"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"
"do so (now or later) by using -b with the checkout command again. Example:\n\n"
" git checkout -b <new-branch-name>\n\n");
"do so (now or later) by using -c with the switch command. Example:\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);
}

View File

@ -3,6 +3,7 @@
#include "git-compat-util.h"
extern int advice_fetch_show_forced_updates;
extern int advice_push_update_rejected;
extern int advice_push_non_ff_current;
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_status_hints;
extern int advice_status_u_option;
extern int advice_status_ahead_behind_warning;
extern int advice_commit_before_merge;
extern int advice_reset_quiet_warning;
extern int advice_resolve_conflict;
extern int advice_sequencer_in_use;
extern int advice_implicit_identity;
extern int advice_detached_head;
extern int advice_set_upstream_failure;

188
apply.c
View File

@ -22,6 +22,12 @@
#include "rerere.h"
#include "apply.h"
struct gitdiff_data {
struct strbuf *root;
int linenr;
int p_value;
};
static void git_apply_config(void)
{
git_config_get_string_const("apply.whitespace", &apply_default_whitespace);
@ -201,40 +207,6 @@ struct fragment {
#define BINARY_DELTA_DEFLATED 1
#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)
{
while (list) {
@ -469,7 +441,7 @@ static char *squash_slash(char *name)
return name;
}
static char *find_name_gnu(struct apply_state *state,
static char *find_name_gnu(struct strbuf *root,
const char *line,
int p_value)
{
@ -478,7 +450,7 @@ static char *find_name_gnu(struct apply_state *state,
/*
* 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)) {
strbuf_release(&name);
@ -495,8 +467,8 @@ static char *find_name_gnu(struct apply_state *state,
}
strbuf_remove(&name, 0, cp - name.buf);
if (state->root.len)
strbuf_insert(&name, 0, state->root.buf, state->root.len);
if (root->len)
strbuf_insert(&name, 0, root->buf, root->len);
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;
}
static char *find_name_common(struct apply_state *state,
static char *find_name_common(struct strbuf *root,
const char *line,
const char *def,
int p_value,
@ -702,30 +674,30 @@ static char *find_name_common(struct apply_state *state,
return squash_slash(xstrdup(def));
}
if (state->root.len) {
char *ret = xstrfmt("%s%.*s", state->root.buf, len, start);
if (root->len) {
char *ret = xstrfmt("%s%.*s", root->buf, len, start);
return squash_slash(ret);
}
return squash_slash(xmemdupz(start, len));
}
static char *find_name(struct apply_state *state,
static char *find_name(struct strbuf *root,
const char *line,
char *def,
int p_value,
int terminate)
{
if (*line == '"') {
char *name = find_name_gnu(state, line, p_value);
char *name = find_name_gnu(root, line, p_value);
if (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,
char *def,
int p_value)
@ -734,7 +706,7 @@ static char *find_name_traditional(struct apply_state *state,
size_t date_len;
if (*line == '"') {
char *name = find_name_gnu(state, line, p_value);
char *name = find_name_gnu(root, line, p_value);
if (name)
return name;
}
@ -742,10 +714,10 @@ static char *find_name_traditional(struct apply_state *state,
len = strchrnul(line, '\n') - line;
date_len = diff_timestamp_len(line, 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;
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))
return -1;
name = find_name_traditional(state, nameline, NULL, 0);
name = find_name_traditional(&state->root, nameline, NULL, 0);
if (!name)
return -1;
cp = strchr(name, '/');
@ -883,17 +855,17 @@ static int parse_traditional_patch(struct apply_state *state,
if (is_dev_null(first)) {
patch->is_new = 1;
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;
} else if (is_dev_null(second)) {
patch->is_new = 0;
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;
} else {
char *first_name;
first_name = find_name_traditional(state, first, NULL, state->p_value);
name = find_name_traditional(state, second, first_name, state->p_value);
first_name = find_name_traditional(&state->root, first, NULL, state->p_value);
name = find_name_traditional(&state->root, second, first_name, state->p_value);
free(first_name);
if (has_epoch_timestamp(first)) {
patch->is_new = 1;
@ -914,7 +886,7 @@ static int parse_traditional_patch(struct apply_state *state,
return 0;
}
static int gitdiff_hdrend(struct apply_state *state,
static int gitdiff_hdrend(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
@ -933,14 +905,14 @@ static int gitdiff_hdrend(struct apply_state *state,
#define DIFF_OLD_NAME 0
#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,
int isnull,
char **name,
int side)
{
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;
}
@ -949,7 +921,7 @@ static int gitdiff_verify_name(struct apply_state *state,
if (isnull)
return error(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
*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)) {
free(another);
return error((side == DIFF_NEW_NAME) ?
@ -965,7 +937,7 @@ static int gitdiff_verify_name(struct apply_state *state,
return 0;
}
static int gitdiff_oldname(struct apply_state *state,
static int gitdiff_oldname(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
@ -974,7 +946,7 @@ static int gitdiff_oldname(struct apply_state *state,
DIFF_OLD_NAME);
}
static int gitdiff_newname(struct apply_state *state,
static int gitdiff_newname(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
@ -992,21 +964,21 @@ static int parse_mode_line(const char *line, int linenr, unsigned int *mode)
return 0;
}
static int gitdiff_oldmode(struct apply_state *state,
static int gitdiff_oldmode(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
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,
struct patch *patch)
{
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,
struct patch *patch)
{
@ -1016,7 +988,7 @@ static int gitdiff_delete(struct apply_state *state,
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,
struct patch *patch)
{
@ -1026,47 +998,47 @@ static int gitdiff_newfile(struct apply_state *state,
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,
struct patch *patch)
{
patch->is_copy = 1;
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;
}
static int gitdiff_copydst(struct apply_state *state,
static int gitdiff_copydst(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
patch->is_copy = 1;
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;
}
static int gitdiff_renamesrc(struct apply_state *state,
static int gitdiff_renamesrc(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
patch->is_rename = 1;
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;
}
static int gitdiff_renamedst(struct apply_state *state,
static int gitdiff_renamedst(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
patch->is_rename = 1;
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;
}
static int gitdiff_similarity(struct apply_state *state,
static int gitdiff_similarity(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
@ -1076,7 +1048,7 @@ static int gitdiff_similarity(struct apply_state *state,
return 0;
}
static int gitdiff_dissimilarity(struct apply_state *state,
static int gitdiff_dissimilarity(struct gitdiff_data *state,
const char *line,
struct patch *patch)
{
@ -1086,7 +1058,7 @@ static int gitdiff_dissimilarity(struct apply_state *state,
return 0;
}
static int gitdiff_index(struct apply_state *state,
static int gitdiff_index(struct gitdiff_data *state,
const char *line,
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
* 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,
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
* 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,
int llen)
{
int nslash;
int i;
if (!state->p_value)
if (!p_value)
return (llen && line[0] == '/') ? NULL : line;
nslash = state->p_value;
nslash = p_value;
for (i = 0; i < llen; i++) {
int ch = line[i];
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,
* 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,
int llen)
{
@ -1184,7 +1156,7 @@ static char *git_header_name(struct apply_state *state,
goto free_and_fail1;
/* 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)
goto free_and_fail1;
strbuf_remove(&first, 0, cp - first.buf);
@ -1201,7 +1173,7 @@ static char *git_header_name(struct apply_state *state,
if (*second == '"') {
if (unquote_c_style(&sp, second, NULL))
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)
goto free_and_fail1;
/* They must match, otherwise ignore */
@ -1212,7 +1184,7 @@ static char *git_header_name(struct apply_state *state,
}
/* unquoted second */
cp = skip_tree_prefix(state, second, line + llen - second);
cp = skip_tree_prefix(p_value, second, line + llen - second);
if (!cp)
goto free_and_fail1;
if (line + llen - cp != first.len ||
@ -1227,7 +1199,7 @@ static char *git_header_name(struct apply_state *state,
}
/* unquoted first name */
name = skip_tree_prefix(state, line, llen);
name = skip_tree_prefix(p_value, line, llen);
if (!name)
return NULL;
@ -1243,7 +1215,7 @@ static char *git_header_name(struct apply_state *state,
if (unquote_c_style(&sp, second, NULL))
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)
goto free_and_fail2;
@ -1287,7 +1259,7 @@ static char *git_header_name(struct apply_state *state,
*/
if (!name[len + 1])
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));
if (!second)
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) +
(patch->is_rename == 1) + (patch->is_copy == 1);
if (extensions > 1)
return error(_("inconsistent header lines %d and %d"),
patch->extension_linenr, state->linenr);
patch->extension_linenr, linenr);
if (extensions && !patch->extension_linenr)
patch->extension_linenr = state->linenr;
patch->extension_linenr = linenr;
return 0;
}
/* Verify that we recognize the lines following a git header */
static int parse_git_header(struct apply_state *state,
const char *line,
int len,
unsigned int size,
struct patch *patch)
int parse_git_diff_header(struct strbuf *root,
int *linenr,
int p_value,
const char *line,
int len,
unsigned int size,
struct patch *patch)
{
unsigned long offset;
struct gitdiff_data parse_hdr_state;
/* A git diff has explicit new/delete information, so we don't guess */
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
* the default name from the header.
*/
patch->def_name = git_header_name(state, line, len);
if (patch->def_name && state->root.len) {
char *s = xstrfmt("%s%s", state->root.buf, patch->def_name);
patch->def_name = git_header_name(p_value, line, len);
if (patch->def_name && root->len) {
char *s = xstrfmt("%s%s", root->buf, patch->def_name);
free(patch->def_name);
patch->def_name = s;
}
line += len;
size -= len;
state->linenr++;
for (offset = len ; size > 0 ; offset += len, size -= len, line += len, state->linenr++) {
(*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 {
const char *str;
int (*fn)(struct apply_state *, const char *, struct patch *);
int (*fn)(struct gitdiff_data *, const char *, struct patch *);
} optable[] = {
{ "@@ -", gitdiff_hdrend },
{ "--- ", gitdiff_oldname },
@ -1377,10 +1355,10 @@ static int parse_git_header(struct apply_state *state,
int res;
if (len < oplen || memcmp(p->str, line, oplen))
continue;
res = p->fn(state, line + oplen, patch);
res = p->fn(&parse_hdr_state, line + oplen, patch);
if (res < 0)
return -1;
if (check_header_line(state, patch))
if (check_header_line(*linenr, patch))
return -1;
if (res > 0)
return offset;
@ -1561,7 +1539,9 @@ static int find_header(struct apply_state *state,
* or mode change, so we handle that specially
*/
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)
return -128;
if (git_hdr_len <= len)
@ -4310,7 +4290,7 @@ static int add_index_file(struct apply_state *state,
"created file '%s'"),
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) {
discard_cache_entry(ce);

48
apply.h
View File

@ -117,6 +117,40 @@ struct apply_state {
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,
struct apply_state *state,
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);
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
* 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;
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);
if (err || !S_ISDIR(mode))
die(_("current working directory is untracked"));

1019
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;
mmfile_t file;
int num_lines;
void *fingerprints;
struct object_id blob_oid;
unsigned short mode;
/* guilty gets set when shipping any suspects to the final
@ -92,6 +94,8 @@ struct blame_entry {
* scanning the lines over and over.
*/
unsigned score;
int ignored;
int unblamable;
};
/*
@ -117,6 +121,8 @@ struct blame_scoreboard {
/* linked list of blames */
struct blame_entry *ent;
struct oidset ignore_list;
/* look-up a line in the final buffer */
int num_lines;
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 object *obj = lookup_object(r, oid->hash);
struct object *obj = lookup_object(r, oid);
if (!obj)
return create_object(r, oid->hash,
alloc_blob_node(r));
return create_object(r, oid, alloc_blob_node(r));
return object_as_type(r, obj, OBJ_BLOB, 0);
}

View File

@ -338,14 +338,19 @@ void create_branch(struct repository *r,
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_rr(r));
unlink(git_path_merge_msg(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));
remove_merge_branch_state(r);
}
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);
/*
* 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
* 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"

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_tree(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_fetch(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_rerere(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_parse(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_stripspace(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_tag(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;
FILE *fp;
if (!get_oid_tree("HEAD", &head))
tree = lookup_tree(the_repository, &head);
else
if (!get_oid("HEAD", &head)) {
struct commit *commit = lookup_commit_or_die(&head, "HEAD");
tree = get_commit_tree(commit);
} else
tree = lookup_tree(the_repository,
the_repository->hash_algo->empty_tree);
@ -1643,11 +1644,8 @@ static int do_interactive(struct am_state *state)
{
assert(state->msg);
if (!isatty(0))
die(_("cannot be interactive without stdin connected to a terminal."));
for (;;) {
const char *reply;
char reply[64];
puts(_("Commit Body is:"));
puts("--------------------------");
@ -1659,11 +1657,11 @@ static int do_interactive(struct am_state *state)
* in your translation. The program will only accept English
* 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) {
continue;
} else if (*reply == 'y' || *reply == 'Y') {
if (*reply == 'y' || *reply == 'Y') {
return 0;
} else if (*reply == 'a' || *reply == 'A') {
state->interactive = 0;
@ -1803,7 +1801,7 @@ next:
*/
if (!state->rebasing) {
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);
}
}
@ -1958,7 +1956,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
if (merge_tree(remote_tree))
return -1;
remove_branch_state(the_repository);
remove_branch_state(the_repository, 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]));
}
if (state.interactive && !paths.argc)
die(_("interactive mode requires patches on the command line"));
am_setup(&state, patch_format, paths.argv, keep_cr);
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);
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,
UPDATE_REFS_MSG_ON_ERR)) {
retval = -1;

View File

@ -53,14 +53,17 @@ static int no_whole_file_rename;
static int show_progress;
static char repeated_meta_color[COLOR_MAXLEN];
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 size_t blame_date_width;
static struct string_list mailmap = STRING_LIST_INIT_NODUP;
#ifndef DEBUG
#define DEBUG 0
#ifndef DEBUG_BLAME
#define DEBUG_BLAME 0
#endif
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);
if (opt & OUTPUT_ANNOTATE_COMPAT) {
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);
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 (color_parse_mem(value, strlen(value), repeated_meta_color))
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);
}
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)
{
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 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 show_stats = 0;
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('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_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-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.reverse = reverse;
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);
lno = sb.num_lines;
@ -1062,7 +1118,7 @@ parse_done:
if (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.show_root = show_root;

View File

@ -47,6 +47,7 @@ static char branch_colors[][COLOR_MAXLEN] = {
GIT_COLOR_NORMAL, /* LOCAL */
GIT_COLOR_GREEN, /* CURRENT */
GIT_COLOR_BLUE, /* UPSTREAM */
GIT_COLOR_CYAN, /* WORKTREE */
};
enum color_branch {
BRANCH_COLOR_RESET = 0,
@ -54,7 +55,8 @@ enum color_branch {
BRANCH_COLOR_REMOTE = 2,
BRANCH_COLOR_LOCAL = 3,
BRANCH_COLOR_CURRENT = 4,
BRANCH_COLOR_UPSTREAM = 5
BRANCH_COLOR_UPSTREAM = 5,
BRANCH_COLOR_WORKTREE = 6
};
static const char *color_branch_slots[] = {
@ -64,6 +66,7 @@ static const char *color_branch_slots[] = {
[BRANCH_COLOR_LOCAL] = "local",
[BRANCH_COLOR_CURRENT] = "current",
[BRANCH_COLOR_UPSTREAM] = "upstream",
[BRANCH_COLOR_WORKTREE] = "worktree",
};
static struct string_list output = STRING_LIST_INIT_DUP;
@ -342,9 +345,10 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
struct strbuf local = STRBUF_INIT;
struct strbuf remote = STRBUF_INIT;
strbuf_addf(&local, "%%(if)%%(HEAD)%%(then)* %s%%(else) %s%%(end)",
branch_get_color(BRANCH_COLOR_CURRENT),
branch_get_color(BRANCH_COLOR_LOCAL));
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_WORKTREE),
branch_get_color(BRANCH_COLOR_LOCAL));
strbuf_addf(&remote, " %s",
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);
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)"
"%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)",
branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));
}
else
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);
} else if (argc > 0 && argc <= 2) {
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)
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.
*/
}
buf = read_object_with_reference(&oid, exp_type, &size, NULL);
buf = read_object_with_reference(the_repository,
&oid, exp_type, &size, NULL);
break;
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_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_lstat_failed = N_("could not lstat %s\n");
enum color_clean {
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_addstr(path, e->d_name);
if (lstat(path->buf, &st))
; /* fall thru */
warning_errno(_(msg_warn_lstat_failed), path->buf);
else if (S_ISDIR(st.st_mode)) {
if (remove_dirs(path, prefix, force_flag, dry_run, quiet, &gone))
ret = 1;

View File

@ -23,6 +23,8 @@
#include "transport.h"
#include "strbuf.h"
#include "dir.h"
#include "dir-iterator.h"
#include "iterator.h"
#include "sigchain.h"
#include "branch.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 list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_NODUP;
static int option_remote_submodules;
static int recurse_submodules_cb(const struct option *opt,
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"),
TRANSPORT_FAMILY_IPV6),
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()
};
@ -354,8 +359,7 @@ static void setup_reference(void)
add_one_reference, &required);
}
static void copy_alternates(struct strbuf *src, struct strbuf *dst,
const char *src_repo)
static void copy_alternates(struct strbuf *src, const char *src_repo)
{
/*
* Read from the source objects/info/alternates file
@ -392,58 +396,63 @@ static void copy_alternates(struct strbuf *src, struct strbuf *dst,
fclose(in);
}
static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
const char *src_repo, int src_baselen)
static void mkdir_if_missing(const char *pathname, mode_t mode)
{
struct stat st;
if (!mkdir(pathname, mode))
return;
if (errno != EEXIST)
die_errno(_("failed to create directory '%s'"), pathname);
else if (stat(pathname, &st))
die_errno(_("failed to stat '%s'"), pathname);
else if (!S_ISDIR(st.st_mode))
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)
{
struct dirent *de;
struct stat buf;
int src_len, dest_len;
DIR *dir;
struct dir_iterator *iter;
int iter_status;
unsigned int flags;
dir = opendir(src->buf);
if (!dir)
die_errno(_("failed to open '%s'"), src->buf);
mkdir_if_missing(dest->buf, 0777);
if (mkdir(dest->buf, 0777)) {
if (errno != EEXIST)
die_errno(_("failed to create directory '%s'"), dest->buf);
else if (stat(dest->buf, &buf))
die_errno(_("failed to stat '%s'"), dest->buf);
else if (!S_ISDIR(buf.st_mode))
die(_("%s exists and is not a directory"), dest->buf);
}
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, '/');
src_len = src->len;
strbuf_addch(dest, '/');
dest_len = dest->len;
while ((de = readdir(dir)) != NULL) {
while ((iter_status = dir_iterator_advance(iter)) == ITER_OK) {
strbuf_setlen(src, src_len);
strbuf_addstr(src, de->d_name);
strbuf_addstr(src, iter->relative_path);
strbuf_setlen(dest, dest_len);
strbuf_addstr(dest, de->d_name);
if (stat(src->buf, &buf)) {
warning (_("failed to stat %s\n"), src->buf);
continue;
}
if (S_ISDIR(buf.st_mode)) {
if (de->d_name[0] != '.')
copy_or_link_directory(src, dest,
src_repo, src_baselen);
strbuf_addstr(dest, iter->relative_path);
if (S_ISDIR(iter->st.st_mode)) {
mkdir_if_missing(dest->buf, 0777);
continue;
}
/* Files that cannot be copied bit-for-bit... */
if (!strcmp(src->buf + src_baselen, "/info/alternates")) {
copy_alternates(src, dest, src_repo);
if (!fspathcmp(iter->relative_path, "info/alternates")) {
copy_alternates(src, src_repo);
continue;
}
if (unlink(dest->buf) && errno != ENOENT)
die_errno(_("failed to unlink '%s'"), dest->buf);
if (!option_no_hardlinks) {
if (!link(src->buf, dest->buf))
if (!link(real_path(src->buf), dest->buf))
continue;
if (option_local > 0)
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))
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)
@ -470,7 +483,7 @@ static void clone_local(const char *src_repo, const char *dest_repo)
get_common_dir(&dest, dest_repo);
strbuf_addstr(&src, "/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(&dest);
}
@ -492,7 +505,7 @@ static enum {
static const char junk_leave_repo_msg[] =
N_("Clone succeeded, but checkout failed.\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)
{
@ -791,6 +804,11 @@ static int checkout(int submodule_progress)
if (option_verbosity < 0)
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);
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);
if (filter_options.choice)
partial_clone_register("origin", &filter_options);
partial_clone_register(option_origin, &filter_options);
if (is_local)
clone_local(path, git_dir);
@ -1245,7 +1263,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
transport_disconnect(transport);
if (option_dissociate) {
close_all_packs(the_repository->objects);
close_object_store(the_repository->objects);
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));
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)
usage_with_options(builtin_column_usage, options);
if (real_command || command) {

View File

@ -5,17 +5,18 @@
#include "parse-options.h"
#include "repository.h"
#include "commit-graph.h"
#include "object-store.h"
static char const * const builtin_commit_graph_usage[] = {
N_("git commit-graph [--object-dir <objdir>]"),
N_("git commit-graph read [--object-dir <objdir>]"),
N_("git commit-graph verify [--object-dir <objdir>]"),
N_("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]"),
N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
NULL
};
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
};
@ -25,7 +26,7 @@ static const char * const builtin_commit_graph_read_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
};
@ -35,9 +36,10 @@ static struct opts_commit_graph {
int stdin_packs;
int stdin_commits;
int append;
int split;
int shallow;
} opts;
static int graph_verify(int argc, const char **argv)
{
struct commit_graph *graph = NULL;
@ -45,11 +47,14 @@ static int graph_verify(int argc, const char **argv)
int open_ok;
int fd;
struct stat st;
int flags = 0;
static struct option builtin_commit_graph_verify_options[] = {
OPT_STRING(0, "object-dir", &opts.obj_dir,
N_("dir"),
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(),
};
@ -59,21 +64,27 @@ static int graph_verify(int argc, const char **argv)
if (!opts.obj_dir)
opts.obj_dir = get_object_directory();
if (opts.shallow)
flags |= COMMIT_GRAPH_VERIFY_SHALLOW;
graph_name = get_commit_graph_filename(opts.obj_dir);
open_ok = open_commit_graph(graph_name, &fd, &st);
if (!open_ok && errno == ENOENT)
return 0;
if (!open_ok)
if (!open_ok && errno != ENOENT)
die_errno(_("Could not open commit-graph '%s'"), graph_name);
graph = load_commit_graph_one_fd_st(fd, &st);
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)
return 1;
return !!open_ok;
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)
@ -135,12 +146,15 @@ static int graph_read(int argc, const char **argv)
}
extern int read_replace_refs;
static struct split_commit_graph_opts split_opts;
static int graph_write(int argc, const char **argv)
{
struct string_list *pack_indexes = NULL;
struct string_list *commit_hex = NULL;
struct string_list lines;
int result = 0;
unsigned int flags = COMMIT_GRAPH_PROGRESS;
static struct option builtin_commit_graph_write_options[] = {
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")),
OPT_BOOL(0, "append", &opts.append,
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(),
};
split_opts.size_multiple = 2;
split_opts.max_commits = 0;
split_opts.expire_time = 0;
argc = parse_options(argc, argv, NULL,
builtin_commit_graph_write_options,
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"));
if (!opts.obj_dir)
opts.obj_dir = get_object_directory();
if (opts.append)
flags |= COMMIT_GRAPH_APPEND;
if (opts.split)
flags |= COMMIT_GRAPH_SPLIT;
read_replace_refs = 0;
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;
}
@ -188,14 +219,15 @@ static int graph_write(int argc, const char **argv)
UNLEAK(buf);
}
write_commit_graph(opts.obj_dir,
pack_indexes,
commit_hex,
opts.append,
1);
if (write_commit_graph(opts.obj_dir,
pack_indexes,
commit_hex,
flags,
&split_opts))
result = 1;
UNLEAK(lines);
return 0;
return result;
}
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");
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[] =
N_("If you wish to skip this commit, use:\n"
N_("and then use:\n"
"\n"
" git reset\n"
" git cherry-pick --continue\n"
"\n"
"Then \"git cherry-pick --continue\" will resume cherry-picking\n"
"the remaining commits.\n");
"to resume cherry-picking 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[] = {
[WT_STATUS_HEADER] = "header",
@ -1078,9 +1081,11 @@ static const char *read_commit_message(const char *name)
static struct status_deferred_config {
enum wt_status_format status_format;
int show_branch;
enum ahead_behind_flags ahead_behind;
} status_deferred_config = {
STATUS_FORMAT_UNSPECIFIED,
-1 /* unspecified */
-1, /* unspecified */
AHEAD_BEHIND_UNSPECIFIED,
};
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)
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)
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);
return 0;
}
if (!strcmp(k, "status.aheadbehind")) {
status_deferred_config.ahead_behind = git_config_bool(k, v);
return 0;
}
if (!strcmp(k, "status.showstash")) {
s->show_stash = git_config_bool(k, v);
return 0;
@ -1658,7 +1678,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
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_msg(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())
die(_("repository has been updated, but unable to write\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))
write_commit_graph_reachable(get_object_directory(), 0, 0);
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
write_commit_graph_reachable(get_object_directory(), 0, NULL))
return 1;
repo_rerere(the_repository, 0);
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