+/fuzz-commit-graph
/fuzz_corpora
/fuzz-pack-headers
/fuzz-pack-idx
/git-rebase--am
/git-rebase--common
/git-rebase--interactive
-/git-rebase--merge
/git-rebase--preserve-merges
/git-receive-pack
/git-reflog
*.pdb
/Debug/
/Release/
+*.dSYM
Benoit Sigoure <tsunanet@gmail.com> <tsuna@lrde.epita.fr>
Bernt Hansen <bernt@norang.ca> <bernt@alumni.uwaterloo.ca>
Brandon Casey <drafnel@gmail.com> <casey@nrlssc.navy.mil>
+Brandon Williams <bwilliams.eng@gmail.com> <bmwill@google.com>
brian m. carlson <sandals@crustytoothpaste.net>
brian m. carlson <sandals@crustytoothpaste.net> <sandals@crustytoothpaste.ath.cx>
Bryan Larsen <bryan@larsen.st> <bryan.larsen@gmail.com>
Christian Couder <chriscool@tuxfamily.org> <christian.couder@gmail.com>
Christian Stimming <stimming@tuhh.de> <chs@ckiste.goetheallee>
Christopher DÃaz Riveros <chrisadr@gentoo.org> Christopher Diaz Riveros
+Clemens Buchacher <drizzd@gmx.net> <drizzd@aon.at>
+Clemens Buchacher <drizzd@gmx.net> <clemens.buchacher@intel.com>
Csaba Henk <csaba@gluster.com> <csaba@lowlife.hu>
Dan Johnson <computerdruid@gmail.com>
Dana L. How <danahow@gmail.com> <how@deathvalley.cswitch.com>
- linux
- osx
+osx_image: xcode10.1
+
compiler:
- clang
- gcc
MAN7_TXT += gittutorial.txt
MAN7_TXT += gitworkflows.txt
+ifdef MAN_FILTER
+MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
+else
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
+MAN_FILTER = $(MAN_TXT)
+endif
+
MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT))
MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT))
GIT_MAN_REF = master
OBSOLETE_HTML += everyday.html
OBSOLETE_HTML += git-remote-helpers.html
-DOC_HTML = $(MAN_HTML) $(OBSOLETE_HTML)
ARTICLES += howto-index
ARTICLES += git-tools
SP_ARTICLES += $(TECH_DOCS)
SP_ARTICLES += technical/api-index
-DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+ARTICLES_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES))
+HTML_FILTER ?= $(ARTICLES_HTML) $(OBSOLETE_HTML)
+DOC_HTML = $(MAN_HTML) $(filter $(HTML_FILTER),$(ARTICLES_HTML) $(OBSOLETE_HTML))
-DOC_MAN1 = $(patsubst %.txt,%.1,$(MAN1_TXT))
-DOC_MAN5 = $(patsubst %.txt,%.5,$(MAN5_TXT))
-DOC_MAN7 = $(patsubst %.txt,%.7,$(MAN7_TXT))
+DOC_MAN1 = $(patsubst %.txt,%.1,$(filter $(MAN_FILTER),$(MAN1_TXT)))
+DOC_MAN5 = $(patsubst %.txt,%.5,$(filter $(MAN_FILTER),$(MAN5_TXT)))
+DOC_MAN7 = $(patsubst %.txt,%.7,$(filter $(MAN_FILTER),$(MAN7_TXT)))
prefix ?= $(HOME)
bindir ?= $(prefix)/bin
lint-docs::
$(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl
+ifeq ($(wildcard po/Makefile),po/Makefile)
+doc-l10n install-l10n::
+ $(MAKE) -C po $@
+endif
+
.PHONY: FORCE
--- /dev/null
+Git 2.21 Release Notes
+======================
+
+Backward Compatibility Notes
+----------------------------
+
+ * Historically, the "-m" (mainline) option can only be used for "git
+ cherry-pick" and "git revert" when working with a merge commit.
+ This version of Git no longer warns or errors out when working with
+ a single-parent commit, as long as the argument to the "-m" option
+ is 1 (i.e. it has only one parent, and the request is to pick or
+ revert relative to that first parent). Scripts that relied on the
+ behaviour may get broken with this change.
+
+
+Updates since v2.20
+-------------------
+
+UI, Workflows & Features
+
+ * The "http.version" configuration variable can be used with recent
+ enough versions of cURL library to force the version of HTTP used
+ to talk when fetching and pushing.
+
+ * Small fixes and features for fast-export and fast-import, mostly on
+ the fast-export side has been made.
+
+ * "git push $there $src:$dst" rejects when $dst is not a fully
+ qualified refname and not clear what the end user meant. The
+ codepath has been taught to give a clearer error message, and also
+ guess where the push should go by taking the type of the pushed
+ object into account (e.g. a tag object would want to go under
+ refs/tags/).
+
+ * "git checkout [<tree-ish>] path..." learned to report the number of
+ paths that have been checked out of the index or the tree-ish,
+ which gives it the same degree of noisy-ness as the case in which
+ the command checks out a branch. "git checkout -m <pathspec>" to
+ undo conflict resolution gives a similar message.
+
+ * "git quiltimport" learned "--keep-non-patch" option.
+
+ * "git worktree remove" and "git worktree move" refused to work when
+ there is a submodule involved. This has been loosened to ignore
+ uninitialized submodules.
+
+ * "git cherry-pick -m1" was forbidden when picking a non-merge
+ commit, even though there _is_ parent number 1 for such a commit.
+ This was done to avoid mistakes back when "cherry-pick" was about
+ picking a single commit, but is no longer useful with "cherry-pick"
+ that can pick a range of commits. Now the "-m$num" option is
+ allowed when picking any commit, as long as $num names an existing
+ parent of the commit.
+
+ * Update "git multimail" from the upstream.
+
+ * "git p4" update.
+
+ * The "--format=<placeholder>" option of for-each-ref, branch and tag
+ learned to show a few more traits of objects that can be learned by
+ the object_info API.
+
+ * "git rebase -i" learned to re-execute a command given with 'exec'
+ to run after it failed the last time.
+
+ * "git diff --color-moved-ws" updates.
+
+ * Custom userformat "log --format" learned %S atom that stands for
+ the tip the traversal reached the commit from, i.e. --source.
+
+ * "git instaweb" learned to drive http.server that comes with
+ "batteries included" Python installation (both Python2 & 3).
+
+ * A new encoding UTF-16LE-BOM has been invented to force encoding to
+ UTF-16 with BOM in little endian byte order, which cannot be directly
+ generated by using iconv.
+
+ * A new date format "--date=human" that morphs its output depending
+ on how far the time is from the current time has been introduced.
+ "--date=auto" can be used to use this new format when the output is
+ going to the pager or to the terminal and otherwise the default
+ format.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * Code clean-up with optimization for the codepath that checks
+ (non-)existence of loose objects.
+
+ * More codepaths have become aware of working with in-core repository
+ instance other than the default "the_repository".
+
+ * The "strncat()" function is now among the banned functions.
+
+ * Portability updates for the HPE NonStop platform.
+
+ * Earlier we added "-Wformat-security" to developer builds, assuming
+ that "-Wall" (which includes "-Wformat" which in turn is required
+ to use "-Wformat-security") is always in effect. This is not true
+ when config.mak.autogen is in use, unfortunately. This has been
+ fixed by unconditionally adding "-Wall" to developer builds.
+
+ * The loose object cache used to optimize existence look-up has been
+ updated.
+
+ * Flaky tests can now be repeatedly run under load with the
+ "--stress" option.
+
+ * Documentation/Makefile is getting prepared for manpage
+ localization.
+
+ * "git fetch-pack" now can talk the version 2 protocol.
+
+ * sha-256 hash has been added and plumbed through the code to allow
+ building Git with the "NewHash".
+
+ * Debugging help for http transport.
+
+ * "git fetch --deepen=<more>" has been corrected to work over v2
+ protocol.
+
+ * The code to walk tree objects has been taught that we may be
+ working with object names that are not computed with SHA-1.
+
+ * The in-core repository instances are passed through more codepaths.
+
+ * Update the protocol message specification to allow only the limited
+ use of scaled quantities. This is ensure potential compatibility
+ issues will not go out of hand.
+
+ * Micro-optimize the code that prepares commit objects to be walked
+ by "git rev-list" when the commit-graph is available.
+
+ * "git fetch" and "git upload-pack" learned to send all exchange over
+ the sideband channel while talking the v2 protocol.
+
+ * The codepath to write out commit-graph has been optimized by
+ following the usual pattern of visiting objects in in-pack order.
+
+ * The codepath to show progress meter while writing out commit-graph
+ file has been improved.
+
+ * Cocci rules have been updated to encourage use of strbuf_addbuf().
+
+ * "git rebase --merge" has been reimplemented by reusing the internal
+ machinery used for "git rebase -i".
+
+ * More code in "git bisect" has been rewritten in C.
+
+ * Instead of going through "git-rebase--am" scriptlet to use the "am"
+ backend, the built-in version of "git rebase" learned to drive the
+ "am" backend directly.
+
+ * The assumption to work on the single "in-core index" instance has
+ been reduced from the library-ish part of the codebase.
+
+ * The test lint learned to catch non-portable "sed" options.
+
+ * "git pack-objects" learned another algorithm to compute the set of
+ objects to send, that trades the resulting packfile off to save
+ traversal cost to favor small pushes.
+
+ * The travis CI scripts have been corrected to build Git with the
+ compiler(s) of our choice.
+
+ * "git submodule update" learned to abort early when core.worktree
+ for the submodule is not set correctly to prevent spreading damage.
+
+ * Test suite has been adjusted to run on Azure Pipeline.
+
+ * Running "Documentation/doc-diff x" from anywhere other than the
+ top-level of the working tree did not show the usage string
+ correctly, which has been fixed.
+
+ * Use of the sparse tool got easier to customize from the command
+ line to help developers.
+
+ * A new target "coverage-prove" to run the coverage test under
+ "prove" has been added.
+
+ * A flakey "p4" test has been removed.
+
+
+Fixes since v2.20
+-----------------
+
+ * Updates for corner cases in merge-recursive.
+ (merge cc4cb0902c en/merge-path-collision later to maint).
+
+ * "git checkout frotz" (without any double-dash) avoids ambiguity by
+ making sure 'frotz' cannot be interpreted as a revision and as a
+ path at the same time. This safety has been updated to check also
+ a unique remote-tracking branch 'frotz' in a remote, when dwimming
+ to create a local branch 'frotz' out of a remote-tracking branch
+ 'frotz' from a remote.
+ (merge be4908f103 nd/checkout-dwim-fix later to maint).
+
+ * Refspecs configured with "git -c var=val clone" did not propagate
+ to the resulting repository, which has been corrected.
+ (merge 7eae4a3ac4 sg/clone-initial-fetch-configuration later to maint).
+
+ * A properly configured username/email is required under
+ user.useConfigOnly in order to create commits; now "git stash"
+ (even though it creates commit objects to represent stash entries)
+ command is exempt from the requirement.
+ (merge 3bc2111fc2 sd/stash-wo-user-name later to maint).
+
+ * The http-backend CGI process did not correctly clean up the child
+ processes it spawns to run upload-pack etc. when it dies itself,
+ which has been corrected.
+ (merge 02818a98d7 mk/http-backend-kill-children-before-exit later to maint).
+
+ * "git rev-list --exclude-promisor-objects" had to take an object
+ that does not exist locally (and is lazily available) from the
+ command line without barfing, but the code dereferenced NULL.
+ (merge 4cf67869b2 md/list-lazy-objects-fix later to maint).
+
+ * The traversal over tree objects has learned to honor
+ ":(attr:label)" pathspec match, which has been implemented only for
+ enumerating paths on the filesystem.
+ (merge 5a0b97b34c nd/attr-pathspec-in-tree-walk later to maint).
+
+ * BSD port updates.
+ (merge 4e3ecbd439 cb/openbsd-allows-reading-directory later to maint).
+ (merge b6bdc2a0f5 cb/t5004-empty-tar-archive-fix later to maint).
+ (merge 82cbc8cde2 cb/test-lint-cp-a later to maint).
+
+ * Lines that begin with a certain keyword that come over the wire, as
+ well as lines that consist only of one of these keywords, ought to
+ be painted in color for easier eyeballing, but the latter was
+ broken ever since the feature was introduced in 2.19, which has
+ been corrected.
+ (merge 1f67290450 hn/highlight-sideband-keywords later to maint).
+
+ * "git log -G<regex>" looked for a hunk in the "git log -p" patch
+ output that contained a string that matches the given pattern.
+ Optimize this code to ignore binary files, which by default will
+ not show any hunk that would match any pattern (unless textconv or
+ the --text option is in effect, that is).
+ (merge e0e7cb8080 tb/log-G-binary later to maint).
+
+ * "git submodule update" ought to use a single job unless asked, but
+ by mistake used multiple jobs, which has been fixed.
+ (merge e3a9d1aca9 sb/submodule-fetchjobs-default-to-one later to maint).
+
+ * "git stripspace" should be usable outside a git repository, but
+ under the "-s" or "-c" mode, it didn't.
+ (merge 957da75802 jn/stripspace-wo-repository later to maint).
+
+ * Some of the documentation pages formatted incorrectly with
+ Asciidoctor, which have been fixed.
+ (merge b62eb1d2f4 ma/asciidoctor later to maint).
+
+ * The core.worktree setting in a submodule repository should not be
+ pointing at a directory when the submodule loses its working tree
+ (e.g. getting deinit'ed), but the code did not properly maintain
+ this invariant.
+
+ * With zsh, "git cmd path<TAB>" was completed to "git cmd path name"
+ when the completed path has a special character like SP in it,
+ without any attempt to keep "path name" a single filename. This
+ has been fixed to complete it to "git cmd path\ name" just like
+ Bash completion does.
+
+ * The test suite tried to see if it is run under bash, but the check
+ itself failed under some other implementations of shell (notably
+ under NetBSD). This has been corrected.
+ (merge 54ea72f09c sg/test-bash-version-fix later to maint).
+
+ * "git gc" and "git repack" did not close the open packfiles that
+ they found unneeded before removing them, which didn't work on a
+ platform incapable of removing an open file. This has been
+ corrected.
+ (merge 5bdece0d70 js/gc-repack-close-before-remove later to maint).
+
+ * The code to drive GIT_EXTERNAL_DIFF command relied on the string
+ returned from getenv() to be non-volatile, which is not true, that
+ has been corrected.
+ (merge 6776a84dae kg/external-diff-save-env later to maint).
+
+ * There were many places the code relied on the string returned from
+ getenv() to be non-volatile, which is not true, that have been
+ corrected.
+ (merge 0da0e9268b jk/save-getenv-result later to maint).
+
+ * The v2 upload-pack protocol implementation failed to honor
+ hidden-ref configuration, which has been corrected.
+ (merge e20b4192a3 jk/proto-v2-hidden-refs-fix later to maint).
+
+ * "git fetch --recurse-submodules" may not fetch the necessary commit
+ that is bound to the superproject, which is getting corrected.
+ (merge be76c21282 sb/submodule-recursive-fetch-gets-the-tip later to maint).
+
+ * "git rebase" internally runs "checkout" to switch between branches,
+ and the command used to call the post-checkout hook, but the
+ reimplementation stopped doing so, which is getting fixed.
+
+ * "git add -e" got confused when the change it wants to let the user
+ edit is smaller than the previous change that was left over in a
+ temporary file.
+ (merge fa6f225e01 js/add-e-clear-patch-before-stating later to maint).
+
+ * "git p4" failed to update a shelved change when there were moved
+ files, which has been corrected.
+ (merge 7a10946ab9 ld/git-p4-shelve-update-fix later to maint).
+
+ * The codepath to read from the commit-graph file attempted to read
+ past the end of it when the file's table-of-contents was corrupt.
+
+ * The compat/obstack code had casts that -Wcast-function-type
+ compilation option found questionable.
+ (merge 764473d257 sg/obstack-cast-function-type-fix later to maint).
+
+ * An obvious typo in an assertion error message has been fixed.
+ (merge 3c27e2e059 cc/test-ref-store-typofix later to maint).
+
+ * In Git for Windows, "git clone \\server\share\path" etc. that uses
+ UNC paths from command line had bad interaction with its shell
+ emulation.
+
+ * "git add --ignore-errors" did not work as advertised and instead
+ worked as an unintended synonym for "git add --renormalize", which
+ has been fixed.
+ (merge e2c2a37545 jk/add-ignore-errors-bit-assignment-fix later to maint).
+
+ * On a case-insensitive filesystem, we failed to compare the part of
+ the path that is above the worktree directory in an absolute
+ pathname, which has been corrected.
+
+ * Asking "git check-attr" about a macro (e.g. "binary") on a specific
+ path did not work correctly, even though "git check-attr -a" listed
+ such a macro correctly. This has been corrected.
+ (merge 7b95849be4 jk/attr-macro-fix later to maint).
+
+ * "git pack-objects" incorrectly used uninitialized mutex, which has
+ been corrected.
+ (merge edb673cf10 ph/pack-objects-mutex-fix later to maint).
+
+ * "git checkout -b <new> [HEAD]" to create a new branch from the
+ current commit and check it out ought to be a no-op in the index
+ and the working tree in normal cases, but there are corner cases
+ that do require updates to the index and the working tree. Running
+ it immediately after "git clone --no-checkout" is one of these
+ cases that an earlier optimization kicked in incorrectly, which has
+ been fixed.
+ (merge 8424bfd45b bp/checkout-new-branch-optim later to maint).
+
+ * "git diff --color-moved --cc --stat -p" did not work well due to
+ funny interaction between a bug in color-moved and the rest, which
+ has been fixed.
+ (merge dac03b5518 jk/diff-cc-stat-fixes later to maint).
+
+ * When GIT_SEQUENCE_EDITOR is set, the command was incorrectly
+ started when modes of "git rebase" that implicitly uses the
+ machinery for the interactive rebase are run, which has been
+ corrected.
+ (merge 891d4a0313 pw/no-editor-in-rebase-i-implicit later to maint).
+
+ * The commit-graph facility did not work when in-core objects that
+ are promoted from unknown type to commit (e.g. a commit that is
+ accessed via a tag that refers to it) were involved, which has been
+ corrected.
+ (merge 4468d4435c sg/object-as-type-commit-graph-fix later to maint).
+
+ * "git fetch" output cleanup.
+ (merge dc40b24df4 nd/fetch-compact-update later to maint).
+
+ * "git cat-file --batch" reported a dangling symbolic link by
+ mistake, when it wanted to report that a given name is ambiguous.
+
+ * Documentation around core.crlf has been updated.
+ (merge c9446f0504 jk/autocrlf-overrides-eol-doc later to maint).
+
+ * The documentation of "git commit-tree" said that the command
+ understands "--gpg-sign" in addition to "-S", but the command line
+ parser did not know about the longhand, which has been corrected.
+
+ * "git rebase -x $cmd" did not reject multi-line command, even though
+ the command is incapable of handling such a command. It now is
+ rejected upfront.
+ (merge c762aada1a pw/rebase-x-sanity-check later to maint).
+
+ * Output from "git help" was not correctly aligned, which has been
+ fixed.
+ (merge 6195a76da4 nd/help-align-command-desc later to maint).
+
+ * The "git submodule summary" subcommand showed shortened commit
+ object names by mechanically truncating them at 7-hexdigit, which
+ has been improved to let "rev-parse --short" scale the length of
+ the abbreviation with the size of the repository.
+ (merge 0586a438f6 sh/submodule-summary-abbrev-fix later to maint).
+
+ * The way the OSX build jobs updates its build environment used the
+ "--quiet" option to "brew update" command, but it wasn't all that
+ quiet to be useful. The use of the option has been replaced with
+ an explicit redirection to the /dev/null (which incidentally would
+ have worked around a breakage by recent updates to homebrew, which
+ has fixed itself already).
+ (merge a1ccaedd62 sg/travis-osx-brew-breakage-workaround later to maint).
+
+ * "git --work-tree=$there --git-dir=$here describe --dirty" did not
+ work correctly as it did not pay attention to the location of the
+ worktree specified by the user by mistake, which has been
+ corrected.
+ (merge c801170b0c ss/describe-dirty-in-the-right-directory later to maint).
+
+ * "git fetch" over protocol v2 that needs to make a second connection
+ to backfill tags did not clear a variable that holds shallow
+ repository information correctly, leading to an access of freed
+ piece of memory.
+
+ * Some errors from the other side coming over smart HTTP transport
+ were not noticed, which has been corrected.
+
+ * Code cleanup, docfix, build fix, etc.
+ (merge 89ba9a79ae hb/t0061-dot-in-path-fix later to maint).
+ (merge d173e799ea sb/diff-color-moved-config-option-fixup later to maint).
+ (merge a8f5a59067 en/directory-renames-nothanks-doc-update later to maint).
+ (merge ec36c42a63 nd/indentation-fix later to maint).
+ (merge f116ee21cd do/gitweb-strict-export-conf-doc later to maint).
+ (merge 112ea42663 fd/gitweb-snapshot-conf-doc-fix later to maint).
+ (merge 1cadad6f65 tb/use-common-win32-pathfuncs-on-cygwin later to maint).
+ (merge 57e9dcaa65 km/rebase-doc-typofix later to maint).
+ (merge b8b4cb27e6 ds/gc-doc-typofix later to maint).
+ (merge 3b3357626e nd/style-opening-brace later to maint).
+ (merge b4583d5595 es/doc-worktree-guessremote-config later to maint).
+ (merge cce99cd8c6 ds/commit-graph-assert-missing-parents later to maint).
+ (merge 0650614982 cy/completion-typofix later to maint).
+ (merge 6881925ef5 rs/sha1-file-close-mapped-file-on-error later to maint).
+ (merge bd8d6f0def en/show-ref-doc-fix later to maint).
+ (merge 1747125e2c cc/partial-clone-doc-typofix later to maint).
+ (merge e01378753d cc/fetch-error-message-fix later to maint).
+ (merge 54e8c11215 jk/remote-insteadof-cleanup later to maint).
+ (merge d609615f48 js/test-git-installed later to maint).
+ (merge ba170517be ja/doc-style-fix later to maint).
+ (merge 86fb1c4e77 km/init-doc-typofix later to maint).
+ (merge 5cfd4a9d10 nd/commit-doc later to maint).
+ (merge 9fce19a431 ab/diff-tree-doc-fix later to maint).
+ (merge 2e285e7803 tz/gpg-test-fix later to maint).
+ (merge 5427de960b kl/pretty-doc-markup-fix later to maint).
+ (merge 3815f64b0d js/mingw-host-cpu later to maint).
tries to overwrite a remote ref that points at an
object that is not a commit-ish, or make the remote
ref point at an object that is not a commit-ish.
+ pushUnqualifiedRefname::
+ Shown when linkgit:git-push[1] gives up trying to
+ guess based on the source and destination refs what
+ remote ref namespace the source belongs in, but where
+ we can still suggest that the user push to either
+ refs/heads/* or refs/tags/* based on the type of the
+ source object.
statusHints::
Show directions on how to proceed from the current
state in the output of linkgit:git-status[1], in
core.eol::
Sets the line ending type to use in the working directory for
- files that have the `text` property set when core.autocrlf is false.
+ files that are marked as text (either by having the `text`
+ attribute set, or by having `text=auto` and Git auto-detecting
+ the contents as text).
Alternatives are 'lf', 'crlf' and 'native', which uses the platform's
native line ending. The default value is `native`. See
linkgit:gitattributes[5] for more information on end-of-line
- conversion.
+ conversion. Note that this value is ignored if `core.autocrlf`
+ is set to `true` or `input`.
core.safecrlf::
If true, makes Git check if converting `CRLF` is reversible when
If set, store cookies received during requests to the file specified by
http.cookieFile. Has no effect if http.cookieFile is unset.
+http.version::
+ Use the specified HTTP protocol version when communicating with a server.
+ If you want to force the default. The available and default version depend
+ on libcurl. Actually the possible values of
+ this option are:
+
+ - HTTP/2
+ - HTTP/1.1
+
http.sslVersion::
The SSL version to use when negotiating an SSL connection, if you
want to force the default. The available and default version
true. You should not generally need to turn this off unless
you are debugging pack bitmaps.
+pack.useSparse::
+ When true, git will default to using the '--sparse' option in
+ 'git pack-objects' when the '--revs' option is present. This
+ algorithm only walks trees that appear in paths that introduce new
+ objects. This can have significant performance benefits when
+ computing a pack to send a small change. However, it is possible
+ that extra objects are added to the pack-file if the included
+ commits contain certain types of direct renames.
+
pack.writeBitmaps (deprecated)::
This is a deprecated synonym for `repack.writeBitmaps`.
-------------------------------------------
+
Defaults to false.
+
+rebase.rescheduleFailedExec::
+ Automatically reschedule `exec` commands that failed. This only makes
+ sense in interactive mode (or when an `--exec` option was provided).
+ This is the same as specifying the `--reschedule-failed-exec` option.
worktree.guessRemote::
- With `add`, if no branch argument, and neither of `-b` nor
- `-B` nor `--detach` are given, the command defaults to
+ If no branch is specified and neither `-b` nor `-B` nor
+ `--detach` is used, then `git worktree add` defaults to
creating a new branch from HEAD. If `worktree.guessRemote` is
set to true, `worktree add` tries to find a remote-tracking
branch whose name uniquely matches the new branch name. If
`dimmed_zebra` is a deprecated synonym.
--
+--no-color-moved::
+ Turn off move detection. This can be used to override configuration
+ settings. It is the same as `--color-moved=no`.
+
--color-moved-ws=<modes>::
- This configures how white spaces are ignored when performing the
+ This configures how whitespace is ignored when performing the
move detection for `--color-moved`.
ifdef::git-diff[]
It can be set by the `diff.colorMovedWS` configuration setting.
These modes can be given as a comma separated list:
+
--
+no::
+ Do not ignore whitespace when performing move detection.
ignore-space-at-eol::
Ignore changes in whitespace at EOL.
ignore-space-change::
Ignore whitespace when comparing lines. This ignores differences
even if one line has whitespace where the other line has none.
allow-indentation-change::
- Initially ignore any white spaces in the move detection, then
+ Initially ignore any whitespace in the move detection, then
group the moved code blocks only into a block if the change in
whitespace is the same per line. This is incompatible with the
other modes.
--
+--no-color-moved-ws::
+ Do not ignore whitespace when performing move detection. This can be
+ used to override configuration settings. It is the same as
+ `--color-moved-ws=no`.
+
--word-diff[=<mode>]::
Show a word diff, using the <mode> to delimit changed words.
By default, words are delimited by whitespace; see
came into being: use the feature iteratively to feed the interesting
block in the preimage back into `-S`, and keep going until you get the
very first version of the block.
++
+Binary files are searched as well.
-G<regex>::
Look for differences whose patch text contains added/removed
-S"regexec\(regexp" --pickaxe-regex` will not (because the number of
occurrences of that string did not change).
+
+Unless `--text` is supplied patches of binary files without a textconv
+filter will be ignored.
++
See the 'pickaxe' entry in linkgit:gitdiffcore[7] for more
information.
shift
done
-cd_to_toplevel
-tmp=Documentation/tmp-doc-diff
+tmp="$(git rev-parse --show-toplevel)/Documentation/tmp-doc-diff" || exit 1
if test -n "$clean"
then
make -j$parallel -C "$tmp/worktree" \
GIT_VERSION=omitted \
SOURCE_DATE_EPOCH=0 \
- DESTDIR="$PWD/$tmp/installed/$1+" \
+ DESTDIR="$tmp/installed/$1+" \
install-man &&
mv "$tmp/installed/$1+" "$tmp/installed/$1"
fi &&
specifying `dir` will record not just a file `dir/file1`
modified in the working tree, a file `dir/file2` added to
the working tree, but also a file `dir/file3` removed from
- the working tree. Note that older versions of Git used
+ the working tree). Note that older versions of Git used
to ignore removed files; use `--no-all` option if you want
- to add modified or new files but ignore removed ones.
+ to add modified or new files but ignore removed ones.
+
For more details about the <pathspec> syntax, see the 'pathspec' entry
in linkgit:gitglossary[7].
--no-ignore-removal::
Update the index not only where the working tree has a file
matching <pathspec> but also where the index already has an
- entry. This adds, modifies, and removes index entries to
+ entry. This adds, modifies, and removes index entries to
match the working tree.
+
If no <pathspec> is given when `-A` option is used, all
--------
* Adds content from all `*.txt` files under `Documentation` directory
-and its subdirectories:
+ and its subdirectories:
+
------------
$ git add Documentation/\*.txt
------------
+
<1> This step and the next one could be combined into a single step with
-"checkout -b my2.6.14 v2.6.14".
+ "checkout -b my2.6.14 v2.6.14".
Delete an unneeded branch::
+
------------
+
<1> Delete the remote-tracking branches "todo", "html" and "man". The next
-'fetch' or 'pull' will create them again unless you configure them not to.
-See linkgit:git-fetch[1].
+ 'fetch' or 'pull' will create them again unless you configure them not to.
+ See linkgit:git-fetch[1].
<2> Delete the "test" branch even if the "master" branch (or whichever branch
-is currently checked out) does not have all commits from the test branch.
+ is currently checked out) does not have all commits from the test branch.
NOTES
stdin, and the SHA-1, type, and size of each object is printed on stdout. The
output format can be overridden using the optional `<format>` argument. If
either `--textconv` or `--filters` was specified, the input is expected to
-list the object names followed by the path name, separated by a single white
-space, so that the appropriate drivers can be determined.
+list the object names followed by the path name, separated by a single
+whitespace, so that the appropriate drivers can be determined.
OPTIONS
-------
Print object information and contents for each object provided
on stdin. May not be combined with any other options or arguments
except `--textconv` or `--filters`, in which case the input lines
- also need to specify the path, separated by white space. See the
+ also need to specify the path, separated by whitespace. See the
section `BATCH OUTPUT` below for details.
--batch-check::
Print object information for each object provided on stdin. May
not be combined with any other options or arguments except
`--textconv` or `--filters`, in which case the input lines also
- need to specify the path, separated by white space. See the
+ need to specify the path, separated by whitespace. See the
section `BATCH OUTPUT` below for details.
--batch-all-objects::
<object> SP missing LF
------------
+If a name is specified that might refer to more than one object (an ambiguous short sha), then `cat-file` will ignore any custom format and print:
+
+------------
+<object> SP ambiguous LF
+------------
+
If --follow-symlinks is used, and a symlink in the repository points
outside the repository, then `cat-file` will ignore any custom format
and print:
Just like linkgit:git-submodule[1], this will detach the
submodules HEAD.
+--no-guess::
+ Do not attempt to create a branch if a remote tracking branch
+ of the same name exists.
+
<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
------------
<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.
+ 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.
+ but leaves HEAD detached.
<3> creates a new tag 'foo', which refers to commit 'f',
-leaving HEAD detached.
+ leaving HEAD detached.
If we have moved away from commit 'f', then we must first recover its object
name (typically by using git reflog), and then we can create a reference to
--------
. The following sequence checks out the `master` branch, reverts
-the `Makefile` to two revisions back, deletes hello.c by
-mistake, and gets it back from the index.
+ the `Makefile` to two revisions back, deletes hello.c by
+ mistake, and gets it back from the index.
+
------------
$ git checkout master <1>
------------
. After working in the wrong branch, switching to the correct
-branch would be done using:
+ branch would be done using:
+
------------
$ git checkout mytopic
changes you made since the tip of the new branch.
. When a merge conflict happens during switching branches with
-the `-m` option, you would see something like this:
+ the `-m` option, you would see something like this:
+
------------
$ git checkout -m mytopic
$ git cherry-pick -Xpatience topic^ <4>
------------
<1> apply the change that would be shown by `git show topic^`.
-In this example, the patch does not apply cleanly, so
-information about the conflict is written to the index and
-working tree and no new commit results.
+ In this example, the patch does not apply cleanly, so
+ information about the conflict is written to the index and
+ working tree and no new commit results.
<2> summarize changes to be reconciled
<3> cancel the cherry-pick. In other words, return to the
-pre-cherry-pick state, preserving any local modifications you had in
-the working tree.
+ pre-cherry-pick state, preserving any local modifications
+ you had in the working tree.
<4> try to apply the change introduced by `topic^` again,
-spending extra time to avoid mistakes based on incorrectly matching
-context lines.
+ spending extra time to avoid mistakes based on incorrectly
+ matching context lines.
SEE ALSO
--------
values are given for the same key, each value will be written to
the config file. This makes it safe, for example, to add
additional fetch refspecs to the origin remote.
++
+Due to limitations of the current implementation, some configuration
+variables do not take effect until after the initial fetch and checkout.
+Configuration variables known to not take effect are:
+`remote.<name>.mirror` and `remote.<name>.tagOpt`. Use the
+corresponding `--mirror` and `--no-tags` options instead.
--depth <depth>::
Create a 'shallow' clone with a history truncated to the
The number of spaces between columns. One space by default.
EXAMPLES
-------
+--------
Format data by columns:
------------
DESCRIPTION
-----------
-Stores the current contents of the index in a new commit along
-with a log message from the user describing the changes.
+Create a new commit containing the current contents of the index and
+the given log message describing the changes. The new commit is a
+direct child of HEAD, usually the tip of the current branch, and the
+branch is updated to point to it (unless no branch is associated with
+the working tree, in which case HEAD is "detached" as described in
+linkgit:git-checkout[1]).
-The content to be added can be specified in several ways:
+The content to be committed can be specified in several ways:
-1. by using 'git add' to incrementally "add" changes to the
- index before using the 'commit' command (Note: even modified
- files must be "added");
+1. by using linkgit:git-add[1] to incrementally "add" changes to the
+ index before using the 'commit' command (Note: even modified files
+ must be "added");
-2. by using 'git rm' to remove files from the working tree
+2. by using linkgit:git-rm[1] to remove files from the working tree
and the index, again before using the 'commit' command;
3. by listing files as arguments to the 'commit' command
<path>...::
If provided, the results are limited to a subset of files
- matching one of these prefix strings.
- i.e., file matches `/^<pattern1>|<pattern2>|.../`
- Note that this parameter does not provide any wildcard or regexp
- features.
+ matching one of the provided pathspecs.
-r::
recurse into sub-trees
include::pretty-formats.txt[]
-
-
-LIMITING OUTPUT
----------------
-If you're only interested in differences in a subset of files, for
-example some architecture-specific files, you might do:
-
- git diff-tree -r <tree-ish> <tree-ish> arch/ia64 include/asm-ia64
-
-and it will only show you what changed in those two directories.
-
-Or if you are searching for what changed in just `kernel/sched.c`, just do
-
- git diff-tree -r <tree-ish> <tree-ish> kernel/sched.c
-
-and it will ignore all differences to other files.
-
-The pattern is always the prefix, and is matched exactly. There are no
-wildcards. Even stricter, it has to match a complete path component.
-I.e. "foo" does not pick up `foobar.h`. "foo" does match `foo/bar.h`
-so it can be used to name subdirectories.
-
-An example of normal usage is:
-
- torvalds@ppc970:~/git> git diff-tree --abbrev 5319e4
- :100664 100664 ac348b... a01513... git-fsck-objects.c
-
-which tells you that the last commit changed just one file (it's from
-this one:
-
------------------------------------------------------------------------------
-commit 3c6f7ca19ad4043e9e72fa94106f352897e651a8
-tree 5319e4d609cdd282069cc4dce33c1db559539b03
-parent b4e628ea30d5ab3606119d2ea5caeab141d38df7
-author Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
-committer Linus Torvalds <torvalds@ppc970.osdl.org> Sat Apr 9 12:02:30 2005
-
-Make "git-fsck-objects" print out all the root commits it finds.
-
-Once I do the reference tracking, I'll also make it print out all the
-HEAD commits it finds, which is even more interesting.
------------------------------------------------------------------------------
-
-in case you care).
-
-
include::diff-format.txt[]
GIT
+
<1> Changes in the working tree not yet staged for the next commit.
<2> Changes between the index and your last commit; what you
-would be committing if you run "git commit" without "-a" option.
+ would be committing if you run "git commit" without "-a" option.
<3> Changes in the working tree since your last commit; what you
-would be committing if you run "git commit -a"
+ would be committing if you run "git commit -a"
Comparing with arbitrary commits::
+
------------
+
<1> Instead of using the tip of the current branch, compare with the
-tip of "test" branch.
+ tip of "test" branch.
<2> Instead of comparing with the tip of "test" branch, compare with
-the tip of the current branch, but limit the comparison to the
-file "test".
+ the tip of the current branch, but limit the comparison to the
+ file "test".
<3> Compare the version before the last commit and the last commit.
Comparing branches::
<1> Changes between the tips of the topic and the master branches.
<2> Same as above.
<3> Changes that occurred on the master branch since when the topic
-branch was started off it.
+ branch was started off it.
Limiting the diff output::
+
------------
+
<1> Show only modification, rename, and copy, but not addition
-or deletion.
+ or deletion.
<2> Show only names and the nature of change, but not actual
-diff output.
+ diff output.
<3> Limit diff output to named subtrees.
Munging the diff output::
------------
+
<1> Spend extra cycles to find renames, copies and complete
-rewrites (very expensive).
+ rewrites (very expensive).
<2> Output diff in reverse.
SEE ALSO
the shape of the history and stored tree. See the section on
`ANONYMIZING` below.
+--reference-excluded-parents::
+ By default, running a command such as `git fast-export
+ master~5..master` will not include the commit master{tilde}5
+ and will make master{tilde}4 no longer have master{tilde}5 as
+ a parent (though both the old master{tilde}4 and new
+ master{tilde}4 will have all the same files). Use
+ --reference-excluded-parents to instead have the the stream
+ refer to commits in the excluded range of history by their
+ sha1sum. Note that the resulting stream can only be used by a
+ repository which already contains the necessary parent
+ commits.
+
+--show-original-ids::
+ Add an extra directive to the output for commits and blobs,
+ `original-oid <SHA1SUM>`. While such directives will likely be
+ ignored by importers such as git-fast-import, it may be useful
+ for intermediary filters (e.g. for rewriting commit messages
+ which refer to older commits, or for stripping blobs by id).
+
--refspec::
Apply the specified refspec to each ref exported. Multiple of them can
be specified.
'git rev-list', that specifies the specific objects and references
to export. For example, `master~10..master` causes the
current master reference to be exported along with all objects
- added since its 10th ancestor commit.
+ added since its 10th ancestor commit and (unless the
+ --reference-excluded-parents option is specified) all files
+ common to master{tilde}9 and master{tilde}10.
EXAMPLES
--------
not contain the old commit).
--quiet::
- Disable all non-fatal output, making fast-import silent when it
- is successful. This option disables the output shown by
- --stats.
+ Disable the output shown by --stats, making fast-import usually
+ be silent when it is successful. However, if the import stream
+ has directives intended to show user output (e.g. `progress`
+ directives), the corresponding messages will still be shown.
--stats::
Display some basic statistics about the objects fast-import has
....
'commit' SP <ref> LF
mark?
+ original-oid?
('author' (SP <name>)? SP LT <email> GT SP <when> LF)?
'committer' (SP <name>)? SP LT <email> GT SP <when> LF
data
to another object simply by reusing the same `<idnum>` in another
`mark` command.
+`original-oid`
+~~~~~~~~~~~~~~
+Provides the name of the object in the original source control system.
+fast-import will simply ignore this directive, but filter processes
+which operate on and modify the stream before feeding to fast-import
+may have uses for this information
+
+....
+ 'original-oid' SP <object-identifier> LF
+....
+
+where `<object-identifer>` is any string not containing LF.
+
`tag`
~~~~~
Creates an annotated tag referring to a specific commit. To create
....
'tag' SP <name> LF
'from' SP <commit-ish> LF
+ original-oid?
'tagger' (SP <name>)? SP LT <email> GT SP <when> LF
data
....
....
'blob' LF
mark?
+ original-oid?
data
....
because it is prefixed with a plus sign; `tmp` will not be.
* Peek at a remote's branch, without configuring the remote in your local
-repository:
+ repository:
+
------------------------------------------------
$ git fetch git://git.kernel.org/pub/scm/git/git.git maint
objectsize::
The size of the object (the same as 'git cat-file -s' reports).
-
+ Append `:disk` to get the size, in bytes, that the object takes up on
+ disk. See the note about on-disk sizes in the `CAVEATS` section below.
objectname::
The object name (aka SHA-1).
For a non-ambiguous abbreviation of the object name append `:short`.
For an abbreviation of the object name with desired length append
`:short=<length>`, where the minimum length is MINIMUM_ABBREV. The
length may be exceeded to ensure unique object names.
+deltabase::
+ This expands to the object name of the delta base for the
+ given object, if it is stored as a delta. Otherwise it
+ expands to the null object name (all zeroes).
upstream::
The name of a local ref which can be considered ``upstream''
git for-each-ref --format="%(refname)%(if)%(authorname)%(then) Authored by: %(authorname)%(end)"
------------
+CAVEATS
+-------
+
+Note that the sizes of objects on disk are reported accurately, but care
+should be taken in drawing conclusions about which refs or objects are
+responsible for disk usage. The size of a packed non-delta object may be
+much larger than the size of objects which delta against it, but the
+choice of which object is the base and which is the delta is arbitrary
+and is subject to change during a repack.
+
+Note also that multiple copies of an object may be present in the object
+database; in this case, it is undefined which copy's size or delta base
+will be reported.
+
SEE ALSO
--------
linkgit:git-show-ref[1]
"mailnews.wraplength" and set the value to 0.
3. Disable the use of format=flowed:
-Edit..Preferences..Advanced..Config Editor. Search for
-"mailnews.send_plaintext_flowed".
-Toggle it to make sure it is set to `false`.
+ Edit..Preferences..Advanced..Config Editor. Search for
+ "mailnews.send_plaintext_flowed".
+ Toggle it to make sure it is set to `false`.
After that is done, you should be able to compose email as you
otherwise would (cut + paste, 'git format-patch' | 'git imap-send', etc),
--------
* Extract commits between revisions R1 and R2, and apply them on top of
-the current branch using 'git am' to cherry-pick them:
+ the current branch using 'git am' to cherry-pick them:
+
------------
$ git format-patch -k --stdout R1..R2 | git am -3 -k
------------
* Extract all commits which are in the current branch but not in the
-origin branch:
+ origin branch:
+
------------
$ git format-patch origin
For each commit a separate file is created in the current directory.
* Extract all commits that lead to 'origin' since the inception of the
-project:
+ project:
+
------------
$ git format-patch --root origin
use it only when you know the recipient uses Git to apply your patch.
* Extract three topmost commits from the current branch and format them
-as e-mailable patches:
+ as e-mailable patches:
+
------------
$ git format-patch -3
The <type> object <object>, is present in the database but never
'directly' used. A dangling commit could be a root node.
-sha1 mismatch <object>::
- The database has an object who's sha1 doesn't match the
- database value.
+hash mismatch <object>::
+ The database has an object whose hash doesn't match the
+ object database value.
This indicates a serious data integrity problem.
Environment Variables
it within all non-bare repos or it can be set to a boolean value.
This defaults to true.
-The optional configuration variable `gc.commitGraph` determines if
+The optional configuration variable `gc.writeCommitGraph` determines if
'git gc' should run 'git commit-graph write'. This can be set to a
boolean value. This defaults to false.
* "man": use the 'man' program as usual,
* "woman": use 'emacsclient' to launch the "woman" mode in emacs
-(this only works starting with emacsclient versions 22),
+ (this only works starting with emacsclient versions 22),
* "konqueror": use 'kfmclient' to open the man page in a new konqueror
-tab (see 'Note about konqueror' below).
+ tab (see 'Note about konqueror' below).
Values for other tools can be used if there is a corresponding
`man.<tool>.cmd` configuration entry (see below).
OPTIONS
-------
---
-
-q::
--quiet::
If you provide a 'directory', the command is run inside it. If this directory
does not exist, it will be created.
---
-
TEMPLATE DIRECTORY
------------------
The default template directory includes some directory structure, suggested
"exclude patterns" (see linkgit:gitignore[5]), and sample hook files.
-The sample hooks are all disabled by default, To enable one of the
+The sample hooks are all disabled by default. To enable one of the
sample hooks rename it by removing its `.sample` suffix.
See linkgit:githooks[5] for more general info on hook execution.
The HTTP daemon command-line that will be executed.
Command-line options may be specified here, and the
configuration file will be added at the end of the command-line.
- Currently apache2, lighttpd, mongoose, plackup and webrick are supported.
+ Currently apache2, lighttpd, mongoose, plackup, python and
+ webrick are supported.
(Default: lighttpd)
-m::
Default format for human-readable dates. (Compare the
`--date` option.) Defaults to "default", which means to write
dates like `Sat May 8 19:35:34 2010 -0500`.
++
+If the format is set to "auto:foo" and the pager is in use, format
+"foo" will be the used for the date format. Otherwise "default" will
+be used.
log.follow::
If `true`, `git log` will act as if the `--follow` option was used when
------------
This:
-1. Creates an empty Git repository in a subdirectory called 'project'.
+1. Creates an empty Git repository in a subdirectory called 'project'.
+
-2. Imports the full contents of the head revision from the given p4
-depot path into a single commit in the Git branch 'refs/remotes/p4/master'.
+2. Imports the full contents of the head revision from the given p4
+ depot path into a single commit in the Git branch 'refs/remotes/p4/master'.
+
-3. Creates a local branch, 'master' from this remote and checks it out.
+3. Creates a local branch, 'master' from this remote and checks it out.
To reproduce the entire p4 history in Git, use the '@all' modifier on
the depot path:
[--local] [--incremental] [--window=<n>] [--depth=<n>]
[--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
[--stdout [--filter=<filter-spec>] | base-name]
- [--shallow] [--keep-true-parents] < object-list
+ [--shallow] [--keep-true-parents] [--sparse] < object-list
DESCRIPTION
Add --no-reuse-object if you want to force a uniform compression
level on all data no matter the source.
+--sparse::
+ Use the "sparse" algorithm to determine which objects to include in
+ the pack, when combined with the "--revs" option. This algorithm
+ only walks trees that appear in paths that introduce new objects.
+ This can have significant performance benefits when computing
+ a pack to send a small change. However, it is possible that extra
+ objects are added to the pack-file if the included commits contain
+ certain types of direct renames.
+
--thin::
Create a "thin" pack by omitting the common objects between a
sender and a receiver in order to reduce network transfer. This
without any `<refspec>` on the command line. Otherwise, missing
`:<dst>` means to update the same ref as the `<src>`.
+
+If <dst> doesn't start with `refs/` (e.g. `refs/heads/master`) we will
+try to infer where in `refs/*` on the destination <repository> it
+belongs based on the the type of <src> being pushed and whether <dst>
+is ambiguous.
++
+--
+* If <dst> unambiguously refers to a ref on the <repository> remote,
+ then push to that ref.
+
+* If <src> resolves to a ref starting with refs/heads/ or refs/tags/,
+ then prepend that to <dst>.
+
+* Other ambiguity resolutions might be added in the future, but for
+ now any other cases will error out with an error indicating what we
+ tried, and depending on the `advice.pushUnqualifiedRefname`
+ configuration (see linkgit:git-config[1]) suggest what refs/
+ namespace you may have wanted to push to.
+
+--
++
The object referenced by <src> is used to update the <dst> reference
on the remote side. Whether this is allowed depends on where in
`refs/*` the <dst> reference lives as described in detail below, in
`refs/remotes/satellite/master`) in the `mothership` repository;
do the same for `dev` and `satellite/dev`.
+
+See the section describing `<refspec>...` above for a discussion of
+the matching semantics.
++
This is to emulate `git fetch` run on the `mothership` using `git
push` that is run in the opposite direction in order to integrate
the work done on `satellite`, and is often necessary when you can
--------
[verse]
'git quiltimport' [--dry-run | -n] [--author <author>] [--patches <dir>]
- [--series <file>]
+ [--series <file>] [--keep-non-patch]
DESCRIPTION
or the value of the `$QUILT_SERIES` environment
variable.
+--keep-non-patch::
+ Pass `-b` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]).
+
GIT
---
Part of the linkgit:git[1] suite
with care: the final stash application after a successful
rebase might result in non-trivial conflicts.
+--reschedule-failed-exec::
+--no-reschedule-failed-exec::
+ Automatically reschedule `exec` commands that failed. This only makes
+ sense in interactive mode (or when an `--exec` option was provided).
+
INCOMPATIBLE OPTIONS
--------------------
-git-rebase has many flags that are incompatible with each other,
-predominantly due to the fact that it has three different underlying
-implementations:
-
- * one based on linkgit:git-am[1] (the default)
- * one based on git-merge-recursive (merge backend)
- * one based on linkgit:git-cherry-pick[1] (interactive backend)
-
-Flags only understood by the am backend:
+The following options:
* --committer-date-is-author-date
* --ignore-date
* --ignore-whitespace
* -C
-Flags understood by both merge and interactive backends:
+are incompatible with the following options:
* --merge
* --strategy
* --strategy-option
* --allow-empty-message
-
-Flags only understood by the interactive backend:
-
* --[no-]autosquash
* --rebase-merges
* --preserve-merges
* --edit-todo
* --root when used in combination with --onto
-Other incompatible flag pairs:
+In addition, the following pairs of options are incompatible:
* --preserve-merges and --interactive
* --preserve-merges and --signoff
Directory rename detection
~~~~~~~~~~~~~~~~~~~~~~~~~~
-The merge and interactive backends work fine with
-directory rename detection. The am backend sometimes does not.
+Directory rename heuristics are enabled in the merge and interactive
+backends. Due to the lack of accurate tree information, directory
+rename detection is disabled in the am backend.
include::merge-strategies.txt[]
At this time, the `merge` command will *always* use the `recursive`
merge strategy for regular merges, and `octopus` for octopus merges,
-strategy, with no way to choose a different one. To work around
+with no way to choose a different one. To work around
this, an `exec` command can be used to call `git merge` explicitly,
using the fact that the labels are worktree-local refs (the ref
`refs/rewritten/onto` would correspond to the label `onto`, for example).
------------
+
<1> You are happily working on something, and find the changes
-in these files are in good order. You do not want to see them
-when you run `git diff`, because you plan to work on other files
-and changes with these files are distracting.
+ in these files are in good order. You do not want to see them
+ when you run `git diff`, because you plan to work on other files
+ and changes with these files are distracting.
<2> Somebody asks you to pull, and the changes sound worthy of merging.
<3> However, you already dirtied the index (i.e. your index does
-not match the `HEAD` commit). But you know the pull you are going
-to make does not affect `frotz.c` or `filfre.c`, so you revert the
-index changes for these two files. Your changes in working tree
-remain there.
+ not match the `HEAD` commit). But you know the pull you are going
+ to make does not affect `frotz.c` or `filfre.c`, so you revert the
+ index changes for these two files. Your changes in working tree
+ remain there.
<4> Then you can pull and merge, leaving `frotz.c` and `filfre.c`
-changes still in the working tree.
+ changes still in the working tree.
Undo a commit and redo::
+
------------
+
<1> This is most often done when you remembered what you
-just committed is incomplete, or you misspelled your commit
-message, or both. Leaves working tree as it was before "reset".
+ just committed is incomplete, or you misspelled your commit
+ message, or both. Leaves working tree as it was before "reset".
<2> Make corrections to working tree files.
<3> "reset" copies the old head to `.git/ORIG_HEAD`; redo the
-commit by starting with its log message. If you do not need to
-edit the message further, you can give `-C` option instead.
+ commit by starting with its log message. If you do not need to
+ edit the message further, you can give `-C` option instead.
+
See also the `--amend` option to linkgit:git-commit[1].
------------
+
<1> You have made some commits, but realize they were premature
-to be in the `master` branch. You want to continue polishing
-them in a topic branch, so create `topic/wip` branch off of the
-current `HEAD`.
+ to be in the `master` branch. You want to continue polishing
+ them in a topic branch, so create `topic/wip` branch off of the
+ current `HEAD`.
<2> Rewind the master branch to get rid of those three commits.
<3> Switch to `topic/wip` branch and keep working.
------------
+
<1> The last three commits (`HEAD`, `HEAD^`, and `HEAD~2`) were bad
-and you do not want to ever see them again. Do *not* do this if
-you have already given these commits to somebody else. (See the
-"RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1] for
-the implications of doing so.)
+ and you do not want to ever see them again. Do *not* do this if
+ you have already given these commits to somebody else. (See the
+ "RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1]
+ for the implications of doing so.)
Undo a merge or pull::
+
------------
+
<1> Try to update from the upstream resulted in a lot of
-conflicts; you were not ready to spend a lot of time merging
-right now, so you decide to do that later.
+ conflicts; you were not ready to spend a lot of time merging
+ right now, so you decide to do that later.
<2> "pull" has not made merge commit, so `git reset --hard`
-which is a synonym for `git reset --hard HEAD` clears the mess
-from the index file and the working tree.
+ which is a synonym for `git reset --hard HEAD` clears the mess
+ from the index file and the working tree.
<3> Merge a topic branch into the current branch, which resulted
-in a fast-forward.
+ in a fast-forward.
<4> But you decided that the topic branch is not ready for public
-consumption yet. "pull" or "merge" always leaves the original
-tip of the current branch in `ORIG_HEAD`, so resetting hard to it
-brings your index file and the working tree back to that state,
-and resets the tip of the branch to that commit.
+ consumption yet. "pull" or "merge" always leaves the original
+ tip of the current branch in `ORIG_HEAD`, so resetting hard to it
+ brings your index file and the working tree back to that state,
+ and resets the tip of the branch to that commit.
Undo a merge or pull inside a dirty working tree::
+
------------
+
<1> Even if you may have local modifications in your
-working tree, you can safely say `git pull` when you know
-that the change in the other branch does not overlap with
-them.
+ working tree, you can safely say `git pull` when you know
+ that the change in the other branch does not overlap with
+ them.
<2> After inspecting the result of the merge, you may find
-that the change in the other branch is unsatisfactory. Running
-`git reset --hard ORIG_HEAD` will let you go back to where you
-were, but it will discard your local changes, which you do not
-want. `git reset --merge` keeps your local changes.
+ that the change in the other branch is unsatisfactory. Running
+ `git reset --hard ORIG_HEAD` will let you go back to where you
+ were, but it will discard your local changes, which you do not
+ want. `git reset --merge` keeps your local changes.
Interrupted workflow::
formatting are ignored.
2. The original format used by Greg Kroah-Hartman's 'send_lots_of_email.pl'
-script
+ script
+
This format expects the first line of the file to contain the "Cc:" value
and the "Subject:" of the message as the second line.
Show the HEAD reference, even if it would normally be filtered out.
---tags::
--heads::
+--tags::
Limit to "refs/heads" and "refs/tags", respectively. These options
are not mutually exclusive; when given both, references stored in
Ignored files are not listed, unless `--ignored` option is in effect,
in which case `XY` are `!!`.
- X Y Meaning
- -------------------------------------------------
- [AMD] not updated
- M [ MD] updated in index
- A [ MD] added to index
- D deleted from index
- R [ MD] renamed in index
- C [ MD] copied in index
- [MARC] index and work tree matches
- [ MARC] M work tree changed since index
- [ MARC] D deleted in work tree
- [ D] R renamed in work tree
- [ D] C copied in work tree
- -------------------------------------------------
- D D unmerged, both deleted
- A U unmerged, added by us
- U D unmerged, deleted by them
- U A unmerged, added by them
- D U unmerged, deleted by us
- A A unmerged, both added
- U U unmerged, both modified
- -------------------------------------------------
- ? ? untracked
- ! ! ignored
- -------------------------------------------------
+....
+X Y Meaning
+-------------------------------------------------
+ [AMD] not updated
+M [ MD] updated in index
+A [ MD] added to index
+D deleted from index
+R [ MD] renamed in index
+C [ MD] copied in index
+[MARC] index and work tree matches
+[ MARC] M work tree changed since index
+[ MARC] D deleted in work tree
+[ D] R renamed in work tree
+[ D] C copied in work tree
+-------------------------------------------------
+D D unmerged, both deleted
+A U unmerged, added by us
+U D unmerged, deleted by them
+U A unmerged, added by them
+D U unmerged, deleted by us
+A A unmerged, both added
+U U unmerged, both modified
+-------------------------------------------------
+? ? untracked
+! ! ignored
+-------------------------------------------------
+....
Submodules have more state and instead report
M the submodule has a different HEAD than
If `--branch` is given, a series of header lines are printed with
information about the current branch.
- Line Notes
- ------------------------------------------------------------
- # branch.oid <commit> | (initial) Current commit.
- # branch.head <branch> | (detached) Current branch.
- # branch.upstream <upstream_branch> If upstream is set.
- # branch.ab +<ahead> -<behind> If upstream is set and
- the commit is present.
- ------------------------------------------------------------
+....
+Line Notes
+------------------------------------------------------------
+# branch.oid <commit> | (initial) Current commit.
+# branch.head <branch> | (detached) Current branch.
+# branch.upstream <upstream_branch> If upstream is set.
+# branch.ab +<ahead> -<behind> If upstream is set and
+ the commit is present.
+------------------------------------------------------------
+....
### Changed Tracked Entries
2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath>
- Field Meaning
- --------------------------------------------------------
- <XY> A 2 character field containing the staged and
- unstaged XY values described in the short format,
- with unchanged indicated by a "." rather than
- a space.
- <sub> A 4 character field describing the submodule state.
- "N..." when the entry is not a submodule.
- "S<c><m><u>" when the entry is a submodule.
- <c> is "C" if the commit changed; otherwise ".".
- <m> is "M" if it has tracked changes; otherwise ".".
- <u> is "U" if there are untracked changes; otherwise ".".
- <mH> The octal file mode in HEAD.
- <mI> The octal file mode in the index.
- <mW> The octal file mode in the worktree.
- <hH> The object name in HEAD.
- <hI> The object name in the index.
- <X><score> The rename or copy score (denoting the percentage
- of similarity between the source and target of the
- move or copy). For example "R100" or "C75".
- <path> The pathname. In a renamed/copied entry, this
- is the target path.
- <sep> When the `-z` option is used, the 2 pathnames are separated
- with a NUL (ASCII 0x00) byte; otherwise, a tab (ASCII 0x09)
- byte separates them.
- <origPath> The pathname in the commit at HEAD or in the index.
- This is only present in a renamed/copied entry, and
- tells where the renamed/copied contents came from.
- --------------------------------------------------------
+....
+Field Meaning
+--------------------------------------------------------
+<XY> A 2 character field containing the staged and
+ unstaged XY values described in the short format,
+ with unchanged indicated by a "." rather than
+ a space.
+<sub> A 4 character field describing the submodule state.
+ "N..." when the entry is not a submodule.
+ "S<c><m><u>" when the entry is a submodule.
+ <c> is "C" if the commit changed; otherwise ".".
+ <m> is "M" if it has tracked changes; otherwise ".".
+ <u> is "U" if there are untracked changes; otherwise ".".
+<mH> The octal file mode in HEAD.
+<mI> The octal file mode in the index.
+<mW> The octal file mode in the worktree.
+<hH> The object name in HEAD.
+<hI> The object name in the index.
+<X><score> The rename or copy score (denoting the percentage
+ of similarity between the source and target of the
+ move or copy). For example "R100" or "C75".
+<path> The pathname. In a renamed/copied entry, this
+ is the target path.
+<sep> When the `-z` option is used, the 2 pathnames are separated
+ with a NUL (ASCII 0x00) byte; otherwise, a tab (ASCII 0x09)
+ byte separates them.
+<origPath> The pathname in the commit at HEAD or in the index.
+ This is only present in a renamed/copied entry, and
+ tells where the renamed/copied contents came from.
+--------------------------------------------------------
+....
Unmerged entries have the following format; the first character is
a "u" to distinguish from ordinary changed entries.
u <xy> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>
- Field Meaning
- --------------------------------------------------------
- <XY> A 2 character field describing the conflict type
- as described in the short format.
- <sub> A 4 character field describing the submodule state
- as described above.
- <m1> The octal file mode in stage 1.
- <m2> The octal file mode in stage 2.
- <m3> The octal file mode in stage 3.
- <mW> The octal file mode in the worktree.
- <h1> The object name in stage 1.
- <h2> The object name in stage 2.
- <h3> The object name in stage 3.
- <path> The pathname.
- --------------------------------------------------------
+....
+Field Meaning
+--------------------------------------------------------
+<XY> A 2 character field describing the conflict type
+ as described in the short format.
+<sub> A 4 character field describing the submodule state
+ as described above.
+<m1> The octal file mode in stage 1.
+<m2> The octal file mode in stage 2.
+<m3> The octal file mode in stage 3.
+<mW> The octal file mode in the worktree.
+<h1> The object name in stage 1.
+<h2> The object name in stage 2.
+<h3> The object name in stage 3.
+<path> The pathname.
+--------------------------------------------------------
+....
### Other Items
the old tag. In that case you can do one of two things:
. The sane thing.
-Just admit you screwed up, and use a different name. Others have
-already seen one tag-name, and if you keep the same name, you
-may be in the situation that two people both have "version X",
-but they actually have 'different' "X"'s. So just call it "X.1"
-and be done with it.
+ Just admit you screwed up, and use a different name. Others have
+ already seen one tag-name, and if you keep the same name, you
+ may be in the situation that two people both have "version X",
+ but they actually have 'different' "X"'s. So just call it "X.1"
+ and be done with it.
. The insane thing.
-You really want to call the new version "X" too, 'even though'
-others have already seen the old one. So just use 'git tag -f'
-again, as if you hadn't already published the old one.
+ You really want to call the new version "X" too, 'even though'
+ others have already seen the old one. So just use 'git tag -f'
+ again, as if you hadn't already published the old one.
However, Git does *not* (and it should not) change tags behind
users back. So if somebody already got the old tag, doing a
program pair is meant to be used to pull updates from a remote
repository. For push operations, see 'git send-pack'.
-
OPTIONS
-------
repository. To control what line ending style is used in the working
directory, use the `eol` attribute for a single file and the
`core.eol` configuration variable for all text files.
-Note that `core.autocrlf` overrides `core.eol`
+Note that setting `core.autocrlf` to `true` or `input` overrides
+`core.eol` (see the definitions of those options in
+linkgit:git-config[1]).
Set::
Use the following attributes if your '*.ps1' files are UTF-16 little
endian encoded without BOM and you want Git to use Windows line endings
-in the working directory. Please note, it is highly recommended to
+in the working directory (use `UTF-16-LE-BOM` instead of `UTF-16LE` if
+you want UTF-16 little endian with BOM).
+Please note, it is highly recommended to
explicitly define the line endings with `eol` if the `working-tree-encoding`
attribute is used to avoid ambiguity.
regular expression. This means that it will detect in-file (or what
rename-detection considers the same file) moves, which is noise. The
implementation runs diff twice and greps, and this can be quite
-expensive.
+expensive. To speed things up binary files without textconv filters
+will be ignored.
When `-S` or `-G` are used without `--pickaxe-all`, only filepairs
that match their respective criterion are kept in the output. When
$strict_export::
Only allow viewing of repositories also shown on the overview page.
- This for example makes `$gitweb_export_ok` file decide if repository is
- available and not only if it is shown. If `$gitweb_list` points to
+ This for example makes `$export_ok` file decide if repository is
+ available and not only if it is shown. If `$projects_list` points to
file with list of project, only those repositories listed would be
available for gitweb. Can be set during building gitweb via
`GITWEB_STRICT_EXPORT`. By default this variable is not set, which
a definitive list. By default only "tgz" is offered.
+
This feature can be configured on a per-repository basis via
-repository's `gitweb.blame` configuration variable, which contains
+repository's `gitweb.snapshot` configuration variable, which contains
a comma separated list of formats or "none" to disable snapshots.
Unknown values are ignored.
- "`!ATTR`" requires that the attribute `ATTR` be
unspecified.
+
+Note that when matching against a tree object, attributes are still
+obtained from working tree, not from the given tree object.
exclude;;
After a path matches any non-exclude pathspec, it will be run
- '%cI': committer date, strict ISO 8601 format
- '%d': ref names, like the --decorate option of linkgit:git-log[1]
- '%D': ref names without the " (", ")" wrapping.
+- '%S': ref name given on the command line by which the commit was reached
+ (like `git log --source`), only works with `git log`
- '%e': encoding
- '%s': subject
- '%f': sanitized subject line, suitable for a filename
`color.diff`, `color.ui`, or `--color`, and respecting the `auto`
settings of the former if we are going to a terminal). `%C(auto,...)`
is accepted as a historical synonym for the default (e.g.,
- `%C(auto,red)`). Specifying `%C(always,...) will show the colors
+ `%C(auto,red)`). Specifying `%C(always,...)` will show the colors
even when color is not otherwise enabled (though consider
just using `--color=always` to enable color for the whole output,
including this format and anything else git might color). `auto`
Note that these are applied before commit
ordering and formatting options, such as `--reverse`.
---
-
-<number>::
-n <number>::
--max-count=<number>::
+
--
1. If the starting point is specified as `ref@{Nth}`, show the index
-format.
+ format.
+
2. If the starting point was specified as `ref@{now}`, show the
-timestamp format.
+ timestamp format.
+
3. If neither was used, but `--date` was given on the command line, show
-the timestamp in the format requested by `--date`.
+ the timestamp in the format requested by `--date`.
+
4. Otherwise, show the index format.
--
`<header>` text will be printed with each progress update.
endif::git-rev-list[]
---
-
History Simplification
~~~~~~~~~~~~~~~~~~~~~~
+
The form '--filter=tree:<depth>' omits all blobs and trees whose depth
from the root tree is >= <depth> (minimum depth if an object is located
-at multiple depths in the commits traversed). Currently, only <depth>=0
-is supported, which omits all blobs and trees.
+at multiple depths in the commits traversed). <depth>=0 will not include
+any trees or blobs unless included explicitly in the command-line (or
+standard input when --stdin is used). <depth>=1 will include only the
+tree and blobs which are referenced directly by a commit reachable from
+<commit> or an explicitly-given object. <depth>=2 is like <depth>=1
+while also including trees and blobs one more level removed from an
+explicitly-given commit or tree.
--no-filter::
Turn off any previous `--filter=` argument.
value (which is always measured in UTC), but does switch the accompanying
timezone value.
+
+`--date=human` shows the timezone if the timezone does not match the
+current time-zone, and doesn't print the whole date if that matches
+(ie skip printing year for dates that are "this year", but also skip
+the whole date itself if it's in the last few days and we can just say
+what weekday it was). For older dates the hour and minute is also
+omitted.
++
`--date=unix` shows the date as a Unix epoch timestamp (seconds since
1970). As with `--raw`, this is always in UTC and therefore `-local`
has no effect.
is not sorted, this function has the side effect of sorting
it.
+`oid_array_filter`::
+ Apply the callback function `want` to each entry in the array,
+ retaining only the entries for which the function returns true.
+ Preserve the order of the entries that are retained.
+
Examples
--------
of the ith commit. Stores value 0x7000000 if no parent in that
position. If there are more than two parents, the second value
has its most-significant bit on and the other bits store an array
- position into the Large Edge List chunk.
+ position into the Extra Edge List chunk.
* The next 8 bytes store the generation number of the commit and
the commit time in seconds since EPOCH. The generation number
uses the higher 30 bits of the first 4 bytes, while the commit
2 bits of the lowest byte, storing the 33rd and 34th bit of the
commit time.
- Large Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional]
+ Extra Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional]
This list of 4-byte values store the second through nth parents for
all octopus merges. The second parent value in the commit data stores
an array position within this list along with the most-significant bit
otherwise noted the usual pkt-line LF rules apply: the sender SHOULD
include a LF, but the receiver MUST NOT complain if it is not present.
+An error packet is a special pkt-line that contains an error string.
+
+----
+ error-line = PKT-LINE("ERR" SP explanation-text)
+----
+
+Throughout the protocol, where `PKT-LINE(...)` is expected, an error packet MAY
+be sent. Once this packet is sent by a client or a server, the data transfer
+process defined in this protocol is terminated.
+
Transports
----------
There are three transports over which the packfile protocol is
"0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
nc -v example.com 9418
-If the server refuses the request for some reasons, it could abort
-gracefully with an error message.
-
-----
- error-line = PKT-LINE("ERR" SP explanation-text)
-----
-
SSH Transport
-------------
Then the server will start sending its packfile data.
----
- server-response = *ack_multi ack / nak / error-line
+ server-response = *ack_multi ack / nak
ack_multi = PKT-LINE("ACK" SP obj-id ack_status)
ack_status = "continue" / "common" / "ready"
ack = PKT-LINE("ACK" SP obj-id)
nak = PKT-LINE("NAK")
- error-line = PKT-LINE("ERR" SP explanation-text)
----
A simple clone may look like this (with no 'have' lines):
that it has, either because the local repository has that object in one of
its promisor packfiles, or because another promisor object refers to it.
+
-When Git encounters a missing object, Git can see if it a promisor object
+When Git encounters a missing object, Git can see if it is a promisor object
and handle it appropriately. If not, Git can report a corruption.
+
This means that there is no need for the client to explicitly maintain an
Request that various objects from the packfile be omitted
using one of several filtering techniques. These are intended
for use with partial clone and partial fetch operations. See
- `rev-list` for possible "filter-spec" values.
+ `rev-list` for possible "filter-spec" values. When communicating
+ with other processes, senders SHOULD translate scaled integers
+ (e.g. "1k") into a fully-expanded form (e.g. "1024") to aid
+ interoperability with older receivers that may not understand
+ newly-invented scaling suffixes. However, receivers SHOULD
+ accept the following suffixes: 'k', 'm', and 'g' for 1024,
+ 1048576, and 1073741824, respectively.
If the 'ref-in-want' feature is advertised, the following argument can
be included in the client's request as well as the potential addition of
particular ref, where <ref> is the full name of a ref on the
server.
+If the 'sideband-all' feature is advertised, the following argument can be
+included in the client's request:
+
+ sideband-all
+ Instruct the server to send the whole response multiplexed, not just
+ the packfile section. All non-flush and non-delim PKT-LINE in the
+ response (not only in the packfile section) will then start with a byte
+ indicating its sideband (1, 2, or 3), and the server may send "0005\2"
+ (a PKT-LINE of sideband 2 with no payload) as a keepalive packet.
+
The response of `fetch` is broken into a number of sections separated by
delimiter packets (0001), with each section beginning with its section
header.
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.20.1
+DEF_VER=v2.21.0-rc0
LF='
'
# in one call to the platform's SHA1_Update(). e.g. APPLE_COMMON_CRYPTO
# wants 'SHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' defined.
#
+# Define BLK_SHA256 to use the built-in SHA-256 routines.
+#
+# Define GCRYPT_SHA256 to use the SHA-256 routines in libgcrypt.
+#
+# Define OPENSSL_SHA256 to use the SHA-256 routines in OpenSSL.
+#
# Define NEEDS_CRYPTO_WITH_SSL if you need -lcrypto when using -lssl (Darwin).
#
# Define NEEDS_SSL_WITH_CRYPTO if you need -lssl when using -lcrypto (Darwin).
export TCL_PATH TCLTK_PATH
-SPARSE_FLAGS =
+# user customisation variable for 'sparse' target
+SPARSE_FLAGS ?=
+# internal/platform customisation variable for 'sparse'
+SP_EXTRA_FLAGS =
+
SPATCH_FLAGS = --all-includes --patch .
SCRIPT_LIB += git-rebase--am
SCRIPT_LIB += git-rebase--common
SCRIPT_LIB += git-rebase--preserve-merges
-SCRIPT_LIB += git-rebase--merge
SCRIPT_LIB += git-sh-setup
SCRIPT_LIB += git-sh-i18n
ETAGS_TARGET = TAGS
+FUZZ_OBJS += fuzz-commit-graph.o
FUZZ_OBJS += fuzz-pack-headers.o
FUZZ_OBJS += fuzz-pack-idx.o
TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
TEST_BUILTINS_OBJS += test-example-decorate.o
TEST_BUILTINS_OBJS += test-genrandom.o
+TEST_BUILTINS_OBJS += test-hash.o
TEST_BUILTINS_OBJS += test-hashmap.o
+TEST_BUILTINS_OBJS += test-hash-speed.o
TEST_BUILTINS_OBJS += test-index-version.o
TEST_BUILTINS_OBJS += test-json-writer.o
TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
TEST_BUILTINS_OBJS += test-sha1.o
TEST_BUILTINS_OBJS += test-sha1-array.o
+TEST_BUILTINS_OBJS += test-sha256.o
TEST_BUILTINS_OBJS += test-sigchain.o
TEST_BUILTINS_OBJS += test-strcmp-offset.o
TEST_BUILTINS_OBJS += test-string-list.o
TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o
TEST_BUILTINS_OBJS += test-subprocess.o
TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
+TEST_BUILTINS_OBJS += test-xml-encode.o
TEST_BUILTINS_OBJS += test-wildmatch.o
TEST_BUILTINS_OBJS += test-windows-named-pipe.o
TEST_BUILTINS_OBJS += test-write-cache.o
endif
endif
+ifdef OPENSSL_SHA256
+ EXTLIBS += $(LIB_4_CRYPTO)
+ BASIC_CFLAGS += -DSHA256_OPENSSL
+else
+ifdef GCRYPT_SHA256
+ BASIC_CFLAGS += -DSHA256_GCRYPT
+ EXTLIBS += -lgcrypt
+else
+ LIB_OBJS += sha256/block/sha256.o
+ BASIC_CFLAGS += -DSHA256_BLK
+endif
+endif
+
ifdef SHA1_MAX_BLOCK_SIZE
LIB_OBJS += compat/sha1-chunked.o
BASIC_CFLAGS += -DSHA1_MAX_BLOCK_SIZE="$(SHA1_MAX_BLOCK_SIZE)"
gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
-DGIT_LOCALE_PATH='"$(localedir_relative_SQ)"'
-http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SPARSE_FLAGS += \
+http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SP_EXTRA_FLAGS += \
-DCURL_DISABLE_TYPECHECK
-pack-revindex.sp: SPARSE_FLAGS += -Wno-memcpy-max-count
+pack-revindex.sp: SP_EXTRA_FLAGS += -Wno-memcpy-max-count
ifdef NO_EXPAT
http-walker.sp http-walker.s http-walker.o: EXTRA_CPPFLAGS = -DNO_EXPAT
ifdef USE_NED_ALLOCATOR
compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \
-DNDEBUG -DREPLACE_SYSTEM_ALLOCATOR
-compat/nedmalloc/nedmalloc.sp: SPARSE_FLAGS += -Wno-non-pointer-null
+compat/nedmalloc/nedmalloc.sp: SP_EXTRA_FLAGS += -Wno-non-pointer-null
endif
git-%$X: %.o GIT-LDFLAGS $(GITLIBS)
$(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE
$(QUIET_SP)cgcc -no-compile $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) \
- $(SPARSE_FLAGS) $<
+ $(SPARSE_FLAGS) $(SP_EXTRA_FLAGS) $<
.PHONY: sparse $(SP_OBJ)
sparse: $(SP_OBJ)
@false
.PHONY: rpm
+artifacts-tar:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) \
+ GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \
+ $(NO_INSTALL) $(MOFILES)
+ $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \
+ SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'
+ test -n "$(ARTIFACTS_DIRECTORY)"
+ mkdir -p "$(ARTIFACTS_DIRECTORY)"
+ $(TAR) czf "$(ARTIFACTS_DIRECTORY)/artifacts.tar.gz" $^ templates/blt/
+.PHONY: artifacts-tar
+
htmldocs = git-htmldocs-$(GIT_VERSION)
manpages = git-manpages-$(GIT_VERSION)
.PHONY: dist-doc distclean
$(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
DEFAULT_TEST_TARGET=test -j1 test
+coverage-prove: coverage-clean-results coverage-compile
+ $(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
+ DEFAULT_TEST_TARGET=prove GIT_PROVE_OPTS="$(GIT_PROVE_OPTS) -j1" \
+ -j1 test
+
coverage-report:
$(QUIET_GCOV)for dir in $(object_dirs); do \
$(GCOV) $(GCOVFLAGS) --object-directory=$$dir $$dir*.c || exit; \
# An example command to build against libFuzzer from LLVM 4.0.0:
#
# make CC=clang CXX=clang++ \
-# FUZZ_CXXFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
+# CFLAGS="-fsanitize-coverage=trace-pc-guard -fsanitize=address" \
# LIB_FUZZING_ENGINE=/usr/lib/llvm-4.0/lib/libFuzzer.a \
# fuzz-all
#
+[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
+
Git - fast, scalable, distributed revision control system
=========================================================
-Documentation/RelNotes/2.20.1.txt
\ No newline at end of file
+Documentation/RelNotes/2.21.0.txt
\ No newline at end of file
int advice_push_already_exists = 1;
int advice_push_fetch_first = 1;
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_commit_before_merge = 1;
{ "pushAlreadyExists", &advice_push_already_exists },
{ "pushFetchFirst", &advice_push_fetch_first },
{ "pushNeedsForce", &advice_push_needs_force },
+ { "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
{ "statusHints", &advice_status_hints },
{ "statusUoption", &advice_status_u_option },
{ "commitBeforeMerge", &advice_commit_before_merge },
extern int advice_push_already_exists;
extern int advice_push_fetch_first;
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_commit_before_merge;
#define SPLIT_CMDLINE_BAD_ENDING 1
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
static const char *split_cmdline_errors[] = {
- "cmdline ends with \\",
- "unclosed quote"
+ N_("cmdline ends with \\"),
+ N_("unclosed quote")
};
int split_cmdline(char *cmdline, const char ***argv)
return obj;
}
-unsigned int alloc_commit_index(struct repository *r)
+static unsigned int alloc_commit_index(struct repository *r)
{
return r->parsed_objects->commit_count++;
}
-void *alloc_commit_node(struct repository *r)
+void init_commit_node(struct repository *r, struct commit *c)
{
- struct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));
c->object.type = OBJ_COMMIT;
c->index = alloc_commit_index(r);
c->graph_pos = COMMIT_NOT_FROM_GRAPH;
c->generation = GENERATION_NUMBER_INFINITY;
+}
+
+void *alloc_commit_node(struct repository *r)
+{
+ struct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));
+ init_commit_node(r, c);
return c;
}
void *alloc_blob_node(struct repository *r);
void *alloc_tree_node(struct repository *r);
+void init_commit_node(struct repository *r, struct commit *c);
void *alloc_commit_node(struct repository *r);
void *alloc_tag_node(struct repository *r);
void *alloc_object_node(struct repository *r);
void alloc_report(struct repository *r);
-unsigned int alloc_commit_index(struct repository *r);
struct alloc_state *allocate_alloc_state(void);
void clear_alloc_state(struct alloc_state *s);
static char *find_name_gnu(struct apply_state *state,
const char *line,
- const char *def,
int p_value)
{
struct strbuf name = STRBUF_INIT;
int terminate)
{
if (*line == '"') {
- char *name = find_name_gnu(state, line, def, p_value);
+ char *name = find_name_gnu(state, line, p_value);
if (name)
return name;
}
size_t date_len;
if (*line == '"') {
- char *name = find_name_gnu(state, line, def, p_value);
+ char *name = find_name_gnu(state, line, p_value);
if (name)
return name;
}
return 0; /* deletion patch */
}
- if (has_sha1_file(oid.hash)) {
+ if (has_object_file(&oid)) {
/* We already have the postimage */
enum object_type type;
unsigned long size;
costate.refresh_cache = 1;
costate.istate = istate;
- if (checkout_entry(ce, &costate, NULL) || lstat(ce->name, st))
+ if (checkout_entry(ce, &costate, NULL, NULL) ||
+ lstat(ce->name, st))
return error(_("cannot checkout %s"), ce->name);
return 0;
}
return read_index_from(state->repo->index, state->index_file,
get_git_dir());
else
- return read_index(state->repo->index);
+ return repo_read_index(state->repo);
}
/* This function tries to read the object name from the current index */
state->index_file,
LOCK_DIE_ON_ERROR);
else
- hold_locked_index(&state->lock_file, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(state->repo, &state->lock_file,
+ LOCK_DIE_ON_ERROR);
}
if (state->check_index && read_apply_cache(state) < 0) {
* string and appends it to a struct strbuf.
*/
static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword,
- const char *value, unsigned int valuelen)
+ const char *value, unsigned int valuelen)
{
int len, tmp;
}
static void format_subst(const struct commit *commit,
- const char *src, size_t len,
- struct strbuf *buf)
+ const char *src, size_t len,
+ struct strbuf *buf)
{
char *to_free = NULL;
struct strbuf fmt = STRBUF_INIT;
git_attr_set_direction(GIT_ATTR_INDEX);
}
- err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
+ err = read_tree_recursive(args->repo, args->tree, "",
+ 0, 0, &args->pathspec,
queue_or_write_archive_entry,
&context);
if (err == READ_TREE_RECURSIVE)
ctx.args = args;
parse_pathspec(&ctx.pathspec, 0, 0, "", paths);
ctx.pathspec.recursive = 1;
- ret = read_tree_recursive(args->tree, "", 0, 0, &ctx.pathspec,
+ ret = read_tree_recursive(args->repo, args->tree, "",
+ 0, 0, &ctx.pathspec,
reject_entry, &ctx);
clear_pathspec(&ctx.pathspec);
return ret != 0;
int refnamelen = colon - name;
if (!dwim_ref(name, refnamelen, &oid, &ref))
- die("no such ref: %.*s", refnamelen, name);
+ die(_("no such ref: %.*s"), refnamelen, name);
free(ref);
}
if (get_oid(name, &oid))
- die("Not a valid object name");
+ die(_("not a valid object name: %s"), name);
commit = lookup_commit_reference_gently(ar_args->repo, &oid, 1);
if (commit) {
tree = parse_tree_indirect(&oid);
if (tree == NULL)
- die("not a tree object");
+ die(_("not a tree object: %s"), oid_to_hex(&oid));
if (prefix) {
struct object_id tree_oid;
err = get_tree_entry(&tree->object.oid, prefix, &tree_oid,
&mode);
if (err || !S_ISDIR(mode))
- die("current working directory is untracked");
+ die(_("current working directory is untracked"));
tree = parse_tree_indirect(&tree_oid);
}
* an insanely large number of attributes.
*/
-#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "exec-cmd.h"
if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen &&
starts_with(name, ATTRIBUTE_MACRO_PREFIX)) {
if (!macro_ok) {
- fprintf(stderr, "%s not allowed: %s:%d\n",
- name, src, lineno);
+ fprintf_ln(stderr, _("%s not allowed: %s:%d"),
+ name, src, lineno);
goto fail_return;
}
is_macro = 1;
const char *path,
struct attr_check *check)
{
- int i, pathlen, rem, dirlen;
+ int pathlen, rem, dirlen;
const char *cp, *last_slash = NULL;
int basename_offset;
all_attrs_init(&g_attr_hashmap, check);
determine_macros(check->all_attrs, check->stack);
- if (check->nr) {
- rem = 0;
- for (i = 0; i < check->nr; i++) {
- int n = check->items[i].attr->attr_nr;
- struct all_attrs_item *item = &check->all_attrs[n];
- if (item->macro) {
- item->value = ATTR__UNSET;
- rem++;
- }
- }
- if (rem == check->nr)
- return;
- }
-
rem = check->all_attrs_nr;
fill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);
}
--- /dev/null
+resources:
+- repo: self
+ fetchDepth: 1
+
+jobs:
+- job: windows_build
+ displayName: Windows Build
+ condition: succeeded()
+ pool: Hosted
+ timeoutInMinutes: 240
+ steps:
+ - powershell: |
+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
+ net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no
+ cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\
+ }
+ displayName: 'Mount test-cache'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - powershell: |
+ $urlbase = "https://dev.azure.com/git-for-windows/git/_apis/build/builds"
+ $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=22&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id
+ $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[1].resource.downloadUrl
+ (New-Object Net.WebClient).DownloadFile($downloadUrl,"git-sdk-64-minimal.zip")
+ Expand-Archive git-sdk-64-minimal.zip -DestinationPath . -Force
+ Remove-Item git-sdk-64-minimal.zip
+
+ # Let Git ignore the SDK and the test-cache
+ "/git-sdk-64-minimal/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude"
+ displayName: 'Download git-sdk-64-minimal'
+ - powershell: |
+ & git-sdk-64-minimal\usr\bin\bash.exe -lc @"
+ ci/make-test-artifacts.sh artifacts
+ "@
+ if (!$?) { exit(1) }
+ displayName: Build
+ env:
+ HOME: $(Build.SourcesDirectory)
+ MSYSTEM: MINGW64
+ DEVELOPER: 1
+ NO_PERL: 1
+ - task: PublishPipelineArtifact@0
+ displayName: 'Publish Pipeline Artifact: test artifacts'
+ inputs:
+ artifactName: 'windows-artifacts'
+ targetPath: '$(Build.SourcesDirectory)\artifacts'
+ - task: PublishPipelineArtifact@0
+ displayName: 'Publish Pipeline Artifact: git-sdk-64-minimal'
+ inputs:
+ artifactName: 'git-sdk-64-minimal'
+ targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal'
+ - powershell: |
+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
+ cmd /c rmdir "$(Build.SourcesDirectory)\test-cache"
+ }
+ displayName: 'Unmount test-cache'
+ condition: true
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+
+- job: windows_test
+ displayName: Windows Test
+ dependsOn: windows_build
+ condition: succeeded()
+ pool: Hosted
+ timeoutInMinutes: 240
+ strategy:
+ parallel: 10
+ steps:
+ - powershell: |
+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
+ net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no
+ cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\
+ }
+ displayName: 'Mount test-cache'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: DownloadPipelineArtifact@0
+ displayName: 'Download Pipeline Artifact: test artifacts'
+ inputs:
+ artifactName: 'windows-artifacts'
+ targetPath: '$(Build.SourcesDirectory)'
+ - task: DownloadPipelineArtifact@0
+ displayName: 'Download Pipeline Artifact: git-sdk-64-minimal'
+ inputs:
+ artifactName: 'git-sdk-64-minimal'
+ targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal'
+ - powershell: |
+ & git-sdk-64-minimal\usr\bin\bash.exe -lc @"
+ test -f artifacts.tar.gz || {
+ echo No test artifacts found\; skipping >&2
+ exit 0
+ }
+ tar xf artifacts.tar.gz || exit 1
+
+ # Let Git ignore the SDK and the test-cache
+ printf '%s\n' /git-sdk-64-minimal/ /test-cache/ >>.git/info/exclude
+
+ ci/run-test-slice.sh `$SYSTEM_JOBPOSITIONINPHASE `$SYSTEM_TOTALJOBSINPHASE || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+ "@
+ if (!$?) { exit(1) }
+ displayName: 'Test (parallel)'
+ env:
+ HOME: $(Build.SourcesDirectory)
+ MSYSTEM: MINGW64
+ NO_SVN_TESTS: 1
+ GIT_TEST_SKIP_REBASE_P: 1
+ - powershell: |
+ if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") {
+ cmd /c rmdir "$(Build.SourcesDirectory)\test-cache"
+ }
+ displayName: 'Unmount test-cache'
+ condition: true
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'windows'
+ platform: Windows
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: linux_clang
+ displayName: linux-clang
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ sudo apt-get update &&
+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin &&
+
+ export CC=clang || exit 1
+
+ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'linux-clang'
+ platform: Linux
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: linux_gcc
+ displayName: linux-gcc
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ sudo add-apt-repository ppa:ubuntu-toolchain-r/test &&
+ sudo apt-get update &&
+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2 language-pack-is git-svn gcc-8 || exit 1
+
+ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'linux-gcc'
+ platform: Linux
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: osx_clang
+ displayName: osx-clang
+ condition: succeeded()
+ pool: Hosted macOS
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ export CC=clang
+
+ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'osx-clang'
+ platform: macOS
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: osx_gcc
+ displayName: osx-gcc
+ condition: succeeded()
+ pool: Hosted macOS
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ ci/install-dependencies.sh || exit 1
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'osx-gcc'
+ platform: macOS
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: gettext_poison
+ displayName: GETTEXT_POISON
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ sudo apt-get update &&
+ sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev &&
+
+ export jobname=GETTEXT_POISON || exit 1
+
+ ci/run-build-and-tests.sh || {
+ ci/print-test-failures.sh
+ exit 1
+ }
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-build-and-tests.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'gettext-poison'
+ platform: Linux
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: linux32
+ displayName: Linux32
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ res=0
+ sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS="$MAKEFLAGS" bash -lxc ci/run-linux32-docker.sh || res=1
+
+ sudo chmod a+r t/out/TEST-*.xml
+ test ! -d t/failed-test-artifacts || sudo chmod a+r t/failed-test-artifacts
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || res=1
+ exit $res
+ displayName: 'ci/run-linux32-docker.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results **/TEST-*.xml'
+ inputs:
+ mergeTestResults: true
+ testRunTitle: 'linux32'
+ platform: Linux
+ publishRunAttachments: false
+ condition: succeededOrFailed()
+ - task: PublishBuildArtifacts@1
+ displayName: 'Publish trash directories of failed tests'
+ condition: failed()
+ inputs:
+ PathtoPublish: t/failed-test-artifacts
+ ArtifactName: failed-test-artifacts
+
+- job: static_analysis
+ displayName: StaticAnalysis
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ sudo apt-get update &&
+ sudo apt-get install -y coccinelle &&
+
+ export jobname=StaticAnalysis &&
+
+ ci/run-static-analysis.sh || exit 1
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/run-static-analysis.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
+
+- job: documentation
+ displayName: Documentation
+ condition: succeeded()
+ pool: Hosted Ubuntu 1604
+ steps:
+ - bash: |
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
+
+ sudo apt-get update &&
+ sudo apt-get install -y asciidoc xmlto asciidoctor &&
+
+ export ALREADY_HAVE_ASCIIDOCTOR=yes. &&
+ export jobname=Documentation &&
+
+ ci/test-documentation.sh || exit 1
+
+ test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
+ displayName: 'ci/test-documentation.sh'
+ env:
+ GITFILESHAREPWD: $(gitfileshare.pwd)
#define strcat(x,y) BANNED(strcat)
#undef strncpy
#define strncpy(x,y,n) BANNED(strncpy)
+#undef strncat
+#define strncat(x,y,n) BANNED(strncat)
#undef sprintf
#undef vsprintf
* is increased by one between each call, but that should not matter
* for this application.
*/
-static unsigned get_prn(unsigned count) {
+static unsigned get_prn(unsigned count)
+{
count = count * 1103515245 + 12345;
return (count/65536) % PRN_MODULO;
}
return skip_away(list, count);
}
-static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
+static void bisect_rev_setup(struct repository *r, struct rev_info *revs,
+ const char *prefix,
const char *bad_format, const char *good_format,
int read_paths)
{
struct argv_array rev_argv = ARGV_ARRAY_INIT;
int i;
- repo_init_revisions(the_repository, revs, prefix);
+ repo_init_revisions(r, revs, prefix);
revs->abbrev = 0;
revs->commit_format = CMIT_FMT_UNSPECIFIED;
if (prepare_revision_walk(revs))
die("revision walk setup failed");
if (revs->tree_objects)
- mark_edges_uninteresting(revs, NULL);
+ mark_edges_uninteresting(revs, NULL, 0);
}
static void exit_if_skipped_commits(struct commit_list *tried,
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
}
-static struct commit *get_commit_reference(const struct object_id *oid)
+static struct commit *get_commit_reference(struct repository *r,
+ const struct object_id *oid)
{
- struct commit *r = lookup_commit_reference(the_repository, oid);
- if (!r)
+ struct commit *c = lookup_commit_reference(r, oid);
+ if (!c)
die(_("Not a valid commit name %s"), oid_to_hex(oid));
- return r;
+ return c;
}
-static struct commit **get_bad_and_good_commits(int *rev_nr)
+static struct commit **get_bad_and_good_commits(struct repository *r,
+ int *rev_nr)
{
struct commit **rev;
int i, n = 0;
ALLOC_ARRAY(rev, 1 + good_revs.nr);
- rev[n++] = get_commit_reference(current_bad_oid);
+ rev[n++] = get_commit_reference(r, current_bad_oid);
for (i = 0; i < good_revs.nr; i++)
- rev[n++] = get_commit_reference(good_revs.oid + i);
+ rev[n++] = get_commit_reference(r, good_revs.oid + i);
*rev_nr = n;
return rev;
free_commit_list(result);
}
-static int check_ancestors(int rev_nr, struct commit **rev, const char *prefix)
+static int check_ancestors(struct repository *r, int rev_nr,
+ struct commit **rev, const char *prefix)
{
struct rev_info revs;
int res;
- bisect_rev_setup(&revs, prefix, "^%s", "%s", 0);
+ bisect_rev_setup(r, &revs, prefix, "^%s", "%s", 0);
bisect_common(&revs);
res = (revs.commits != NULL);
* If a merge base must be tested by the user, its source code will be
* checked out to be tested by the user and we will exit.
*/
-static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
+static void check_good_are_ancestors_of_bad(struct repository *r,
+ const char *prefix,
+ int no_checkout)
{
char *filename = git_pathdup("BISECT_ANCESTORS_OK");
struct stat st;
goto done;
/* Check if all good revs are ancestor of the bad rev. */
- rev = get_bad_and_good_commits(&rev_nr);
- if (check_ancestors(rev_nr, rev, prefix))
+ rev = get_bad_and_good_commits(r, &rev_nr);
+ if (check_ancestors(r, rev_nr, rev, prefix))
check_merge_bases(rev_nr, rev, no_checkout);
free(rev);
/*
* This does "git diff-tree --pretty COMMIT" without one fork+exec.
*/
-static void show_diff_tree(const char *prefix, struct commit *commit)
+static void show_diff_tree(struct repository *r,
+ const char *prefix,
+ struct commit *commit)
{
struct rev_info opt;
/* diff-tree init */
- repo_init_revisions(the_repository, &opt, prefix);
+ repo_init_revisions(r, &opt, prefix);
git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
opt.abbrev = 0;
opt.diff = 1;
* If no_checkout is non-zero, the bisection process does not
* checkout the trial commit but instead simply updates BISECT_HEAD.
*/
-int bisect_next_all(const char *prefix, int no_checkout)
+int bisect_next_all(struct repository *r, const char *prefix, int no_checkout)
{
struct rev_info revs;
struct commit_list *tried;
if (read_bisect_refs())
die(_("reading bisect refs failed"));
- check_good_are_ancestors_of_bad(prefix, no_checkout);
+ check_good_are_ancestors_of_bad(r, prefix, no_checkout);
- bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
+ bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1);
revs.limited = 1;
bisect_common(&revs);
exit_if_skipped_commits(tried, current_bad_oid);
printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
term_bad);
- show_diff_tree(prefix, revs.commits->item);
+ show_diff_tree(r, prefix, revs.commits->item);
/* This means the bisection process succeeded. */
exit(10);
}
#define BISECT_H
struct commit_list;
+struct repository;
/*
* Find bisection. If something is found, `reaches` will be the number of
const char *header_prefix;
};
-extern int bisect_next_all(const char *prefix, int no_checkout);
+extern int bisect_next_all(struct repository *r,
+ const char *prefix,
+ int no_checkout);
extern int estimate_bisect_steps(int all);
die("no such path '%s' in HEAD", path);
}
-static struct commit_list **append_parent(struct commit_list **tail, const struct object_id *oid)
+static struct commit_list **append_parent(struct repository *r,
+ struct commit_list **tail,
+ const struct object_id *oid)
{
struct commit *parent;
- parent = lookup_commit_reference(the_repository, oid);
+ parent = lookup_commit_reference(r, oid);
if (!parent)
die("no such commit %s", oid_to_hex(oid));
return &commit_list_insert(parent, tail)->next;
}
-static void append_merge_parents(struct commit_list **tail)
+static void append_merge_parents(struct repository *r,
+ struct commit_list **tail)
{
int merge_head;
struct strbuf line = STRBUF_INIT;
- merge_head = open(git_path_merge_head(the_repository), O_RDONLY);
+ merge_head = open(git_path_merge_head(r), O_RDONLY);
if (merge_head < 0) {
if (errno == ENOENT)
return;
die("cannot open '%s' for reading",
- git_path_merge_head(the_repository));
+ git_path_merge_head(r));
}
while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
struct object_id oid;
if (line.len < GIT_SHA1_HEXSZ || get_oid_hex(line.buf, &oid))
die("unknown line in '%s': %s",
- git_path_merge_head(the_repository), line.buf);
- tail = append_parent(tail, &oid);
+ git_path_merge_head(r), line.buf);
+ tail = append_parent(r, tail, &oid);
}
close(merge_head);
strbuf_release(&line);
* want to transfer ownership of the buffer to the commit (so we
* must use detach).
*/
-static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
+static void set_commit_buffer_from_strbuf(struct repository *r,
+ struct commit *c,
+ struct strbuf *sb)
{
size_t len;
void *buf = strbuf_detach(sb, &len);
- set_commit_buffer(the_repository, c, buf, len);
+ set_commit_buffer(r, c, buf, len);
}
/*
unsigned mode;
struct strbuf msg = STRBUF_INIT;
- read_index(r->index);
+ repo_read_index(r);
time(&now);
- commit = alloc_commit_node(the_repository);
+ commit = alloc_commit_node(r);
commit->object.parsed = 1;
commit->date = now;
parent_tail = &commit->parents;
if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
die("no such ref: HEAD");
- parent_tail = append_parent(parent_tail, &head_oid);
- append_merge_parents(parent_tail);
+ parent_tail = append_parent(r, parent_tail, &head_oid);
+ append_merge_parents(r, parent_tail);
verify_working_tree_path(r, commit, path);
origin = make_origin(commit, path);
ident, ident, path,
(!contents_from ? path :
(!strcmp(contents_from, "-") ? "standard input" : contents_from)));
- set_commit_buffer_from_strbuf(commit, &msg);
+ set_commit_buffer_from_strbuf(r, commit, &msg);
if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
* want to run "diff-index --cached".
*/
discard_index(r->index);
- read_index(r->index);
+ repo_read_index(r);
len = strlen(path);
if (!mode) {
struct object *obj = revs->pending.objects[i].item;
if (obj->flags & UNINTERESTING)
continue;
- obj = deref_tag(the_repository, obj, NULL, 0);
+ obj = deref_tag(revs->repo, obj, NULL, 0);
if (obj->type != OBJ_COMMIT)
die("Non commit %s?", revs->pending.objects[i].name);
if (found)
/* Is that sole rev a committish? */
obj = revs->pending.objects[0].item;
- obj = deref_tag(the_repository, obj, NULL, 0);
+ obj = deref_tag(revs->repo, obj, NULL, 0);
if (obj->type != OBJ_COMMIT)
return NULL;
/* Do we have HEAD? */
if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
return NULL;
- head_commit = lookup_commit_reference_gently(the_repository,
+ head_commit = lookup_commit_reference_gently(revs->repo,
&head_oid, 1);
if (!head_commit)
return NULL;
struct object *obj = revs->pending.objects[i].item;
if (!(obj->flags & UNINTERESTING))
continue;
- obj = deref_tag(the_repository, obj, NULL, 0);
+ obj = deref_tag(revs->repo, obj, NULL, 0);
if (obj->type != OBJ_COMMIT)
die("Non commit %s?", revs->pending.objects[i].name);
if (found)
"will track its remote counterpart, you may want to use\n"
"\"git push -u\" to set the upstream config as you push.");
-void create_branch(const char *name, const char *start_name,
+void create_branch(struct repository *r,
+ const char *name, const char *start_name,
int force, int clobber_head_ok, int reflog,
int quiet, enum branch_track track)
{
break;
}
- if ((commit = lookup_commit_reference(the_repository, &oid)) == NULL)
+ if ((commit = lookup_commit_reference(r, &oid)) == NULL)
die(_("Not a valid branch point: '%s'."), start_name);
oidcpy(&oid, &commit->object.oid);
free(real_ref);
}
-void remove_branch_state(void)
+void remove_branch_state(struct repository *r)
{
- unlink(git_path_cherry_pick_head(the_repository));
- unlink(git_path_revert_head(the_repository));
- unlink(git_path_merge_head(the_repository));
- unlink(git_path_merge_rr(the_repository));
- unlink(git_path_merge_msg(the_repository));
- unlink(git_path_merge_mode(the_repository));
- unlink(git_path_squash_msg(the_repository));
+ unlink(git_path_cherry_pick_head(r));
+ unlink(git_path_revert_head(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));
+ unlink(git_path_squash_msg(r));
}
void die_if_checked_out(const char *branch, int ignore_current_worktree)
#ifndef BRANCH_H
#define BRANCH_H
+struct repository;
struct strbuf;
enum branch_track {
/*
* Creates a new branch, where:
*
+ * - r is the repository to add a branch to
+ *
* - name is the new branch name
*
* - start_name is the name of the existing branch that the new branch should
* that start_name is a tracking branch for (if any).
*
*/
-void create_branch(const char *name, const char *start_name,
+void create_branch(struct repository *r,
+ const char *name, const char *start_name,
int force, int clobber_head_ok,
int reflog, int quiet, enum branch_track track);
* Remove information about the state of working on the current
* branch. (E.g., MERGE_HEAD)
*/
-void remove_branch_state(void);
+void remove_branch_state(struct repository *r);
/*
* Configure local branch "local" as downstream to branch "remote"
*
* Copyright (C) 2006 Linus Torvalds
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
continue; /* do not touch non blobs */
if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
continue;
- retval |= add_file_to_cache(ce->name, flags | HASH_RENORMALIZE);
+ retval |= add_file_to_cache(ce->name, flags | ADD_CACHE_RENORMALIZE);
}
return retval;
die(_("pathspec '%s' did not match any files"),
pathspec->items[i].match);
}
- free(seen);
+ free(seen);
}
int run_add_interactive(const char *revision, const char *patch_mode,
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
rev.diffopt.use_color = 0;
rev.diffopt.flags.ignore_dirty_submodules = 1;
- out = open(file, O_CREAT | O_WRONLY, 0666);
+ out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (out < 0)
die(_("Could not open '%s' for writing."), file);
rev.diffopt.file = xfdopen(out, "w");
*
* Based on git-am.sh by Junio C Hamano.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
#include "packfile.h"
#include "repository.h"
-/**
- * Returns 1 if the file is empty or does not exist, 0 otherwise.
- */
-static int is_empty_file(const char *filename)
-{
- struct stat st;
-
- if (stat(filename, &st) < 0) {
- if (errno == ENOENT)
- return 1;
- die_errno(_("could not stat %s"), filename);
- }
-
- return !st.st_size;
-}
-
/**
* Returns the length of the first line of msg.
*/
}
finish:
- finish_copy_notes_for_rewrite(c, msg);
+ finish_copy_notes_for_rewrite(the_repository, c, msg);
fclose(fp);
strbuf_release(&sb);
return ret;
goto finish;
}
- if (is_empty_file(am_path(state, "patch"))) {
+ if (is_empty_or_missing_file(am_path(state, "patch"))) {
printf_ln(_("Patch is empty."));
die_user_resolve(state);
}
* changes.
*/
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
o.branch1 = "HEAD";
their_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
refresh_and_write_cache();
- if (index_has_changes(&the_index, NULL, &sb)) {
+ if (repo_index_has_changes(the_repository, NULL, &sb)) {
write_state_bool(state, "dirtyindex", 1);
die(_("Dirty index: cannot apply patches (dirty: %s)"), sb.buf);
}
* the result may have produced the same tree as ours.
*/
if (!apply_status &&
- !index_has_changes(&the_index, NULL, NULL)) {
+ !repo_index_has_changes(the_repository, NULL, NULL)) {
say(state, stdout, _("No changes -- Patch already applied."));
goto next;
}
resume = 0;
}
- if (!is_empty_file(am_path(state, "rewritten"))) {
+ if (!is_empty_or_missing_file(am_path(state, "rewritten"))) {
assert(state->rebasing);
copy_notes_for_rebase(state);
run_post_rewrite_hook(state);
say(state, stdout, _("Applying: %.*s"), linelen(state->msg), state->msg);
- if (!index_has_changes(&the_index, NULL, NULL)) {
+ if (!repo_index_has_changes(the_repository, NULL, NULL)) {
printf_ln(_("No changes - did you forget to use 'git add'?\n"
"If there is nothing left to stage, chances are that something else\n"
"already introduced the same changes; you might want to skip this patch."));
if (merge_tree(remote_tree))
return -1;
- remove_branch_state();
+ remove_branch_state(the_repository);
return 0;
}
static void am_rerere_clear(void)
{
struct string_list merge_rr = STRING_LIST_INIT_DUP;
- rerere_clear(&merge_rr);
+ rerere_clear(the_repository, &merge_rr);
string_list_clear(&merge_rr, 1);
}
if (clean_index(&head, &head))
die(_("failed to clean index"));
+ if (state->rebasing) {
+ FILE *fp = xfopen(am_path(state, "rewritten"), "a");
+
+ assert(!is_null_oid(&state->orig_commit));
+ fprintf(fp, "%s ", oid_to_hex(&state->orig_commit));
+ fprintf(fp, "%s\n", oid_to_hex(&head));
+ fclose(fp);
+ }
+
am_next(state);
am_load(state);
am_run(state, 0);
/* Ensure a valid committer ident can be constructed */
git_committer_info(IDENT_STRICT);
- if (read_index_preload(&the_index, NULL, 0) < 0)
+ if (repo_read_index_preload(the_repository, NULL, 0) < 0)
die(_("failed to read the index"));
if (in_progress) {
const char *remote, const char *exec,
const char *name_hint)
{
- char *buf;
int fd[2], i, rv;
struct transport *transport;
struct remote *_remote;
+ struct packet_reader reader;
_remote = remote_get(remote);
if (!_remote->url[0])
packet_write_fmt(fd[1], "argument %s\n", argv[i]);
packet_flush(fd[1]);
- buf = packet_read_line(fd[0], NULL);
- if (!buf)
+ packet_reader_init(&reader, fd[0], NULL, 0,
+ PACKET_READ_CHOMP_NEWLINE |
+ PACKET_READ_DIE_ON_ERR_PACKET);
+
+ if (packet_reader_read(&reader) != PACKET_READ_NORMAL)
die(_("git archive: expected ACK/NAK, got a flush packet"));
- if (strcmp(buf, "ACK")) {
- if (starts_with(buf, "NACK "))
- die(_("git archive: NACK %s"), buf + 5);
- if (starts_with(buf, "ERR "))
- die(_("remote error: %s"), buf + 4);
+ if (strcmp(reader.line, "ACK")) {
+ if (starts_with(reader.line, "NACK "))
+ die(_("git archive: NACK %s"), reader.line + 5);
die(_("git archive: protocol error"));
}
- if (packet_read_line(fd[0], NULL))
+ if (packet_reader_read(&reader) != PACKET_READ_FLUSH)
die(_("git archive: expected a flush"));
/* Now, start reading from fd[0] and spit it out to stdout */
#include "parse-options.h"
#include "bisect.h"
#include "refs.h"
+#include "dir.h"
+#include "argv-array.h"
+#include "run-command.h"
+#include "prompt.h"
+#include "quote.h"
static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
+static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
+static GIT_PATH_FUNC(git_path_bisect_head, "BISECT_HEAD")
+static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
+static GIT_PATH_FUNC(git_path_head_name, "head-name")
+static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
static const char * const git_bisect_helper_usage[] = {
N_("git bisect--helper --next-all [--no-checkout]"),
N_("git bisect--helper --write-terms <bad_term> <good_term>"),
N_("git bisect--helper --bisect-clean-state"),
+ N_("git bisect--helper --bisect-reset [<commit>]"),
+ N_("git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>"),
+ N_("git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>"),
+ N_("git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]"),
+ N_("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]"),
+ N_("git bisect--helper --bisect-start [--term-{old,good}=<term> --term-{new,bad}=<term>]"
+ "[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]"),
NULL
};
+struct bisect_terms {
+ char *term_good;
+ char *term_bad;
+};
+
+static void free_terms(struct bisect_terms *terms)
+{
+ FREE_AND_NULL(terms->term_good);
+ FREE_AND_NULL(terms->term_bad);
+}
+
+static void set_terms(struct bisect_terms *terms, const char *bad,
+ const char *good)
+{
+ free((void *)terms->term_good);
+ terms->term_good = xstrdup(good);
+ free((void *)terms->term_bad);
+ terms->term_bad = xstrdup(bad);
+}
+
+static const char *vocab_bad = "bad|new";
+static const char *vocab_good = "good|old";
+
/*
* Check whether the string `term` belongs to the set of strings
* included in the variable arguments.
}
}
+static int bisect_reset(const char *commit)
+{
+ struct strbuf branch = STRBUF_INIT;
+
+ if (!commit) {
+ if (strbuf_read_file(&branch, git_path_bisect_start(), 0) < 1) {
+ printf(_("We are not bisecting.\n"));
+ return 0;
+ }
+ strbuf_rtrim(&branch);
+ } else {
+ struct object_id oid;
+
+ if (get_oid_commit(commit, &oid))
+ return error(_("'%s' is not a valid commit"), commit);
+ strbuf_addstr(&branch, commit);
+ }
+
+ if (!file_exists(git_path_bisect_head())) {
+ struct argv_array argv = ARGV_ARRAY_INIT;
+
+ argv_array_pushl(&argv, "checkout", branch.buf, "--", NULL);
+ if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
+ strbuf_release(&branch);
+ argv_array_clear(&argv);
+ return error(_("could not check out original"
+ " HEAD '%s'. Try 'git bisect"
+ " reset <commit>'."), branch.buf);
+ }
+ argv_array_clear(&argv);
+ }
+
+ strbuf_release(&branch);
+ return bisect_clean_state();
+}
+
+static void log_commit(FILE *fp, char *fmt, const char *state,
+ struct commit *commit)
+{
+ struct pretty_print_context pp = {0};
+ struct strbuf commit_msg = STRBUF_INIT;
+ char *label = xstrfmt(fmt, state);
+
+ format_commit_message(commit, "%s", &commit_msg, &pp);
+
+ fprintf(fp, "# %s: [%s] %s\n", label, oid_to_hex(&commit->object.oid),
+ commit_msg.buf);
+
+ strbuf_release(&commit_msg);
+ free(label);
+}
+
+static int bisect_write(const char *state, const char *rev,
+ const struct bisect_terms *terms, int nolog)
+{
+ struct strbuf tag = STRBUF_INIT;
+ struct object_id oid;
+ struct commit *commit;
+ FILE *fp = NULL;
+ int retval = 0;
+
+ if (!strcmp(state, terms->term_bad)) {
+ strbuf_addf(&tag, "refs/bisect/%s", state);
+ } else if (one_of(state, terms->term_good, "skip", NULL)) {
+ strbuf_addf(&tag, "refs/bisect/%s-%s", state, rev);
+ } else {
+ retval = error(_("Bad bisect_write argument: %s"), state);
+ goto finish;
+ }
+
+ if (get_oid(rev, &oid)) {
+ retval = error(_("couldn't get the oid of the rev '%s'"), rev);
+ goto finish;
+ }
+
+ if (update_ref(NULL, tag.buf, &oid, NULL, 0,
+ UPDATE_REFS_MSG_ON_ERR)) {
+ retval = -1;
+ goto finish;
+ }
+
+ fp = fopen(git_path_bisect_log(), "a");
+ if (!fp) {
+ retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
+ goto finish;
+ }
+
+ commit = lookup_commit_reference(the_repository, &oid);
+ log_commit(fp, "%s", state, commit);
+
+ if (!nolog)
+ fprintf(fp, "git bisect %s %s\n", state, rev);
+
+finish:
+ if (fp)
+ fclose(fp);
+ strbuf_release(&tag);
+ return retval;
+}
+
+static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
+{
+ int has_term_file = !is_empty_or_missing_file(git_path_bisect_terms());
+
+ if (one_of(cmd, "skip", "start", "terms", NULL))
+ return 0;
+
+ if (has_term_file && strcmp(cmd, terms->term_bad) &&
+ strcmp(cmd, terms->term_good))
+ return error(_("Invalid command: you're currently in a "
+ "%s/%s bisect"), terms->term_bad,
+ terms->term_good);
+
+ if (!has_term_file) {
+ if (one_of(cmd, "bad", "good", NULL)) {
+ set_terms(terms, "bad", "good");
+ return write_terms(terms->term_bad, terms->term_good);
+ }
+ if (one_of(cmd, "new", "old", NULL)) {
+ set_terms(terms, "new", "old");
+ return write_terms(terms->term_bad, terms->term_good);
+ }
+ }
+
+ return 0;
+}
+
+static int mark_good(const char *refname, const struct object_id *oid,
+ int flag, void *cb_data)
+{
+ int *m_good = (int *)cb_data;
+ *m_good = 0;
+ return 1;
+}
+
+static const char *need_bad_and_good_revision_warning =
+ N_("You need to give me at least one %s and %s revision.\n"
+ "You can use \"git bisect %s\" and \"git bisect %s\" for that.");
+
+static const char *need_bisect_start_warning =
+ N_("You need to start by \"git bisect start\".\n"
+ "You then need to give me at least one %s and %s revision.\n"
+ "You can use \"git bisect %s\" and \"git bisect %s\" for that.");
+
+static int bisect_next_check(const struct bisect_terms *terms,
+ const char *current_term)
+{
+ int missing_good = 1, missing_bad = 1, retval = 0;
+ const char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
+ const char *good_glob = xstrfmt("%s-*", terms->term_good);
+
+ if (ref_exists(bad_ref))
+ missing_bad = 0;
+
+ for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
+ (void *) &missing_good);
+
+ if (!missing_good && !missing_bad)
+ goto finish;
+
+ if (!current_term) {
+ retval = -1;
+ goto finish;
+ }
+
+ if (missing_good && !missing_bad &&
+ !strcmp(current_term, terms->term_good)) {
+ char *yesno;
+ /*
+ * have bad (or new) but not good (or old). We could bisect
+ * although this is less optimum.
+ */
+ warning(_("bisecting only with a %s commit"), terms->term_bad);
+ if (!isatty(0))
+ goto finish;
+ /*
+ * TRANSLATORS: Make sure to include [Y] and [n] in your
+ * translation. The program will only accept English input
+ * at this point.
+ */
+ yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
+ if (starts_with(yesno, "N") || starts_with(yesno, "n"))
+ retval = -1;
+ goto finish;
+ }
+ if (!is_empty_or_missing_file(git_path_bisect_start())) {
+ retval = error(_(need_bad_and_good_revision_warning),
+ vocab_bad, vocab_good, vocab_bad, vocab_good);
+ } else {
+ retval = error(_(need_bisect_start_warning),
+ vocab_good, vocab_bad, vocab_good, vocab_bad);
+ }
+
+finish:
+ free((void *) good_glob);
+ free((void *) bad_ref);
+ return retval;
+}
+
+static int get_terms(struct bisect_terms *terms)
+{
+ struct strbuf str = STRBUF_INIT;
+ FILE *fp = NULL;
+ int res = 0;
+
+ fp = fopen(git_path_bisect_terms(), "r");
+ if (!fp) {
+ res = -1;
+ goto finish;
+ }
+
+ free_terms(terms);
+ strbuf_getline_lf(&str, fp);
+ terms->term_bad = strbuf_detach(&str, NULL);
+ strbuf_getline_lf(&str, fp);
+ terms->term_good = strbuf_detach(&str, NULL);
+
+finish:
+ if (fp)
+ fclose(fp);
+ strbuf_release(&str);
+ return res;
+}
+
+static int bisect_terms(struct bisect_terms *terms, const char *option)
+{
+ if (get_terms(terms))
+ return error(_("no terms defined"));
+
+ if (option == NULL) {
+ printf(_("Your current terms are %s for the old state\n"
+ "and %s for the new state.\n"),
+ terms->term_good, terms->term_bad);
+ return 0;
+ }
+ if (one_of(option, "--term-good", "--term-old", NULL))
+ printf("%s\n", terms->term_good);
+ else if (one_of(option, "--term-bad", "--term-new", NULL))
+ printf("%s\n", terms->term_bad);
+ else
+ return error(_("invalid argument %s for 'git bisect terms'.\n"
+ "Supported options are: "
+ "--term-good|--term-old and "
+ "--term-bad|--term-new."), option);
+
+ return 0;
+}
+
+static int bisect_append_log_quoted(const char **argv)
+{
+ int retval = 0;
+ FILE *fp = fopen(git_path_bisect_log(), "a");
+ struct strbuf orig_args = STRBUF_INIT;
+
+ if (!fp)
+ return -1;
+
+ if (fprintf(fp, "git bisect start") < 1) {
+ retval = -1;
+ goto finish;
+ }
+
+ sq_quote_argv(&orig_args, argv);
+ if (fprintf(fp, "%s\n", orig_args.buf) < 1)
+ retval = -1;
+
+finish:
+ fclose(fp);
+ strbuf_release(&orig_args);
+ return retval;
+}
+
+static int bisect_start(struct bisect_terms *terms, int no_checkout,
+ const char **argv, int argc)
+{
+ int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0;
+ int flags, pathspec_pos, retval = 0;
+ struct string_list revs = STRING_LIST_INIT_DUP;
+ struct string_list states = STRING_LIST_INIT_DUP;
+ struct strbuf start_head = STRBUF_INIT;
+ struct strbuf bisect_names = STRBUF_INIT;
+ struct object_id head_oid;
+ struct object_id oid;
+ const char *head;
+
+ if (is_bare_repository())
+ no_checkout = 1;
+
+ /*
+ * Check for one bad and then some good revisions
+ */
+ for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[i], "--")) {
+ has_double_dash = 1;
+ break;
+ }
+ }
+
+ for (i = 0; i < argc; i++) {
+ const char *arg = argv[i];
+ if (!strcmp(argv[i], "--")) {
+ break;
+ } else if (!strcmp(arg, "--no-checkout")) {
+ no_checkout = 1;
+ } else if (!strcmp(arg, "--term-good") ||
+ !strcmp(arg, "--term-old")) {
+ must_write_terms = 1;
+ free((void *) terms->term_good);
+ terms->term_good = xstrdup(argv[++i]);
+ } else if (skip_prefix(arg, "--term-good=", &arg) ||
+ skip_prefix(arg, "--term-old=", &arg)) {
+ must_write_terms = 1;
+ free((void *) terms->term_good);
+ terms->term_good = xstrdup(arg);
+ } else if (!strcmp(arg, "--term-bad") ||
+ !strcmp(arg, "--term-new")) {
+ must_write_terms = 1;
+ free((void *) terms->term_bad);
+ terms->term_bad = xstrdup(argv[++i]);
+ } else if (skip_prefix(arg, "--term-bad=", &arg) ||
+ skip_prefix(arg, "--term-new=", &arg)) {
+ must_write_terms = 1;
+ free((void *) terms->term_bad);
+ terms->term_bad = xstrdup(arg);
+ } else if (starts_with(arg, "--") &&
+ !one_of(arg, "--term-good", "--term-bad", NULL)) {
+ return error(_("unrecognized option: '%s'"), arg);
+ } else {
+ char *commit_id = xstrfmt("%s^{commit}", arg);
+ if (get_oid(commit_id, &oid) && has_double_dash)
+ die(_("'%s' does not appear to be a valid "
+ "revision"), arg);
+
+ string_list_append(&revs, oid_to_hex(&oid));
+ free(commit_id);
+ }
+ }
+ pathspec_pos = i;
+
+ /*
+ * The user ran "git bisect start <sha1> <sha1>", hence did not
+ * explicitly specify the terms, but we are already starting to
+ * set references named with the default terms, and won't be able
+ * to change afterwards.
+ */
+ if (revs.nr)
+ must_write_terms = 1;
+ for (i = 0; i < revs.nr; i++) {
+ if (bad_seen) {
+ string_list_append(&states, terms->term_good);
+ } else {
+ bad_seen = 1;
+ string_list_append(&states, terms->term_bad);
+ }
+ }
+
+ /*
+ * Verify HEAD
+ */
+ head = resolve_ref_unsafe("HEAD", 0, &head_oid, &flags);
+ if (!head)
+ if (get_oid("HEAD", &head_oid))
+ return error(_("bad HEAD - I need a HEAD"));
+
+ /*
+ * Check if we are bisecting
+ */
+ if (!is_empty_or_missing_file(git_path_bisect_start())) {
+ /* Reset to the rev from where we started */
+ strbuf_read_file(&start_head, git_path_bisect_start(), 0);
+ strbuf_trim(&start_head);
+ if (!no_checkout) {
+ struct argv_array argv = ARGV_ARRAY_INIT;
+
+ argv_array_pushl(&argv, "checkout", start_head.buf,
+ "--", NULL);
+ if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
+ retval = error(_("checking out '%s' failed."
+ " Try 'git bisect start "
+ "<valid-branch>'."),
+ start_head.buf);
+ goto finish;
+ }
+ }
+ } else {
+ /* Get the rev from where we start. */
+ if (!get_oid(head, &head_oid) &&
+ !starts_with(head, "refs/heads/")) {
+ strbuf_reset(&start_head);
+ strbuf_addstr(&start_head, oid_to_hex(&head_oid));
+ } else if (!get_oid(head, &head_oid) &&
+ skip_prefix(head, "refs/heads/", &head)) {
+ /*
+ * This error message should only be triggered by
+ * cogito usage, and cogito users should understand
+ * it relates to cg-seek.
+ */
+ if (!is_empty_or_missing_file(git_path_head_name()))
+ return error(_("won't bisect on cg-seek'ed tree"));
+ strbuf_addstr(&start_head, head);
+ } else {
+ return error(_("bad HEAD - strange symbolic ref"));
+ }
+ }
+
+ /*
+ * Get rid of any old bisect state.
+ */
+ if (bisect_clean_state())
+ return -1;
+
+ /*
+ * In case of mistaken revs or checkout error, or signals received,
+ * "bisect_auto_next" below may exit or misbehave.
+ * We have to trap this to be able to clean up using
+ * "bisect_clean_state".
+ */
+
+ /*
+ * Write new start state
+ */
+ write_file(git_path_bisect_start(), "%s\n", start_head.buf);
+
+ if (no_checkout) {
+ get_oid(start_head.buf, &oid);
+ if (update_ref(NULL, "BISECT_HEAD", &oid, NULL, 0,
+ UPDATE_REFS_MSG_ON_ERR)) {
+ retval = -1;
+ goto finish;
+ }
+ }
+
+ if (pathspec_pos < argc - 1)
+ sq_quote_argv(&bisect_names, argv + pathspec_pos);
+ write_file(git_path_bisect_names(), "%s\n", bisect_names.buf);
+
+ for (i = 0; i < states.nr; i++)
+ if (bisect_write(states.items[i].string,
+ revs.items[i].string, terms, 1)) {
+ retval = -1;
+ goto finish;
+ }
+
+ if (must_write_terms && write_terms(terms->term_bad,
+ terms->term_good)) {
+ retval = -1;
+ goto finish;
+ }
+
+ retval = bisect_append_log_quoted(argv);
+ if (retval)
+ retval = -1;
+
+finish:
+ string_list_clear(&revs, 0);
+ string_list_clear(&states, 0);
+ strbuf_release(&start_head);
+ strbuf_release(&bisect_names);
+ return retval;
+}
+
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
enum {
NEXT_ALL = 1,
WRITE_TERMS,
BISECT_CLEAN_STATE,
- CHECK_EXPECTED_REVS
+ CHECK_EXPECTED_REVS,
+ BISECT_RESET,
+ BISECT_WRITE,
+ CHECK_AND_SET_TERMS,
+ BISECT_NEXT_CHECK,
+ BISECT_TERMS,
+ BISECT_START
} cmdmode = 0;
- int no_checkout = 0;
+ int no_checkout = 0, res = 0, nolog = 0;
struct option options[] = {
OPT_CMDMODE(0, "next-all", &cmdmode,
N_("perform 'git bisect next'"), NEXT_ALL),
N_("cleanup the bisection state"), BISECT_CLEAN_STATE),
OPT_CMDMODE(0, "check-expected-revs", &cmdmode,
N_("check for expected revs"), CHECK_EXPECTED_REVS),
+ OPT_CMDMODE(0, "bisect-reset", &cmdmode,
+ N_("reset the bisection state"), BISECT_RESET),
+ OPT_CMDMODE(0, "bisect-write", &cmdmode,
+ N_("write out the bisection state in BISECT_LOG"), BISECT_WRITE),
+ OPT_CMDMODE(0, "check-and-set-terms", &cmdmode,
+ N_("check and set terms in a bisection state"), CHECK_AND_SET_TERMS),
+ OPT_CMDMODE(0, "bisect-next-check", &cmdmode,
+ N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK),
+ OPT_CMDMODE(0, "bisect-terms", &cmdmode,
+ N_("print out the bisect terms"), BISECT_TERMS),
+ OPT_CMDMODE(0, "bisect-start", &cmdmode,
+ N_("start the bisect session"), BISECT_START),
OPT_BOOL(0, "no-checkout", &no_checkout,
N_("update BISECT_HEAD instead of checking out the current commit")),
+ OPT_BOOL(0, "no-log", &nolog,
+ N_("no log for BISECT_WRITE")),
OPT_END()
};
+ struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
argc = parse_options(argc, argv, prefix, options,
- git_bisect_helper_usage, 0);
+ git_bisect_helper_usage,
+ PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_UNKNOWN);
if (!cmdmode)
usage_with_options(git_bisect_helper_usage, options);
switch (cmdmode) {
case NEXT_ALL:
- return bisect_next_all(prefix, no_checkout);
+ return bisect_next_all(the_repository, prefix, no_checkout);
case WRITE_TERMS:
if (argc != 2)
return error(_("--write-terms requires two arguments"));
case CHECK_EXPECTED_REVS:
check_expected_revs(argv, argc);
return 0;
+ case BISECT_RESET:
+ if (argc > 1)
+ return error(_("--bisect-reset requires either no argument or a commit"));
+ return !!bisect_reset(argc ? argv[0] : NULL);
+ case BISECT_WRITE:
+ if (argc != 4 && argc != 5)
+ return error(_("--bisect-write requires either 4 or 5 arguments"));
+ set_terms(&terms, argv[3], argv[2]);
+ res = bisect_write(argv[0], argv[1], &terms, nolog);
+ break;
+ case CHECK_AND_SET_TERMS:
+ if (argc != 3)
+ return error(_("--check-and-set-terms requires 3 arguments"));
+ set_terms(&terms, argv[2], argv[1]);
+ res = check_and_set_terms(&terms, argv[0]);
+ break;
+ case BISECT_NEXT_CHECK:
+ if (argc != 2 && argc != 3)
+ return error(_("--bisect-next-check requires 2 or 3 arguments"));
+ set_terms(&terms, argv[1], argv[0]);
+ res = bisect_next_check(&terms, argc == 3 ? argv[2] : NULL);
+ break;
+ case BISECT_TERMS:
+ if (argc > 1)
+ return error(_("--bisect-terms requires 0 or 1 argument"));
+ res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
+ break;
+ case BISECT_START:
+ set_terms(&terms, "bad", "good");
+ res = bisect_start(&terms, no_checkout, argv, argc);
+ break;
default:
return error("BUG: unknown subcommand '%d'", cmdmode);
}
- return 0;
+ free_terms(&terms);
+ return !!res;
}
*/
blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */
break;
+ case DATE_HUMAN:
+ /* If the year is shown, no time is shown */
+ blame_date_width = sizeof("Thu Oct 19 16:00");
+ break;
case DATE_NORMAL:
blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
break;
long bottom, top;
if (parse_range_arg(range_list.items[range_i].string,
nth_line_cb, &sb, lno, anchor,
- &bottom, &top, sb.path, &the_index))
+ &bottom, &top, sb.path,
+ the_repository->index))
usage(blame_usage);
if ((!lno && (top || bottom)) || lno < bottom)
die(Q_("file %s has only %lu line",
* create_branch takes care of setting up the tracking
* info and making sure new_upstream is correct
*/
- create_branch(branch->name, new_upstream, 0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
+ create_branch(the_repository, branch->name, new_upstream,
+ 0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
} else if (unset_upstream) {
struct branch *branch = branch_get(argv[0]);
struct strbuf buf = STRBUF_INIT;
if (track == BRANCH_TRACK_OVERRIDE)
die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead."));
- create_branch(argv[0], (argc == 2) ? argv[1] : head,
+ create_branch(the_repository,
+ argv[0], (argc == 2) ? argv[1] : head,
force, 0, reflog, quiet, track);
} else
usage(builtin_bundle_usage);
return 1;
}
- if (verify_bundle(&header, 1))
+ if (verify_bundle(the_repository, &header, 1))
return 1;
fprintf(stderr, _("%s is okay\n"), bundle_file);
return 0;
}
if (!startup_info->have_repository)
die(_("Need a repository to create a bundle."));
- return !!create_bundle(&header, bundle_file, argc, argv);
+ return !!create_bundle(the_repository, bundle_file, argc, argv);
} else if (!strcmp(cmd, "unbundle")) {
if (!startup_info->have_repository)
die(_("Need a repository to unbundle."));
- return !!unbundle(&header, bundle_fd, 0) ||
+ return !!unbundle(the_repository, &header, bundle_fd, 0) ||
list_bundle_refs(&header, argc, argv);
} else
usage(builtin_bundle_usage);
*
* Copyright (C) Linus Torvalds, 2005
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "config.h"
#include "builtin.h"
if (unknown_type)
flags |= OBJECT_INFO_ALLOW_UNKNOWN_TYPE;
- if (get_oid_with_context(obj_name, GET_OID_RECORD_PATH,
+ if (get_oid_with_context(the_repository, obj_name,
+ GET_OID_RECORD_PATH,
&oid, &obj_context))
die("Not a valid object name %s", obj_name);
/*
* After a mark_query run, this object_info is set up to be
- * passed to sha1_object_info_extended. It will point to the data
+ * passed to oid_object_info_extended. It will point to the data
* elements above, so you can retrieve the response from there.
*/
struct object_info info;
/*
* This flag will be true if the requested batch format and options
- * don't require us to call sha1_object_info, which can then be
+ * don't require us to call oid_object_info, which can then be
* optimized out.
*/
unsigned skip_object_info : 1;
{
struct object_context ctx;
int flags = opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0;
- enum follow_symlinks_result result;
+ enum get_oid_result result;
- result = get_oid_with_context(obj_name, flags, &data->oid, &ctx);
+ result = get_oid_with_context(the_repository, obj_name,
+ flags, &data->oid, &ctx);
if (result != FOUND) {
switch (result) {
case MISSING_OBJECT:
printf("%s missing\n", obj_name);
break;
+ case SHORT_NAME_AMBIGUOUS:
+ printf("%s ambiguous\n", obj_name);
+ break;
case DANGLING_SYMLINK:
printf("dangling %"PRIuMAX"\n%s\n",
(uintmax_t)strlen(obj_name), obj_name);
/*
* Expand once with our special mark_query flag, which will prime the
- * object_info to be handed to sha1_object_info_extended for each
+ * object_info to be handed to oid_object_info_extended for each
* object.
*/
memset(&data, 0, sizeof(data));
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
* Copyright (C) 2005 Linus Torvalds
*
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
continue;
did_checkout = 1;
if (checkout_entry(ce, &state,
- to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
+ to_tempfile ? topath[ce_stage(ce)] : NULL,
+ NULL) < 0)
errs++;
}
write_tempfile_record(last_ce->name, prefix);
}
if (checkout_entry(ce, &state,
- to_tempfile ? topath[ce_stage(ce)] : NULL) < 0)
+ to_tempfile ? topath[ce_stage(ce)] : NULL,
+ NULL) < 0)
errs++;
last_ce = ce;
}
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "checkout.h"
int ignore_skipworktree;
int ignore_other_worktrees;
int show_progress;
+ int count_checkout_paths;
/*
* If new checkout options are added, skip_merge_working_tree
* should be updated accordingly.
static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
{
- read_tree_recursive(tree, "", 0, 0, pathspec, update_some, NULL);
+ read_tree_recursive(the_repository, tree, "", 0, 0,
+ pathspec, update_some, NULL);
/* update the index with the given tree's info
* for all args, expanding wildcards, and exit
}
static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
- const struct checkout *state)
+ const struct checkout *state, int *nr_checkouts)
{
while (pos < active_nr &&
!strcmp(active_cache[pos]->name, ce->name)) {
if (ce_stage(active_cache[pos]) == stage)
- return checkout_entry(active_cache[pos], state, NULL);
+ return checkout_entry(active_cache[pos], state,
+ NULL, nr_checkouts);
pos++;
}
if (stage == 2)
return error(_("path '%s' does not have their version"), ce->name);
}
-static int checkout_merged(int pos, const struct checkout *state)
+static int checkout_merged(int pos, const struct checkout *state, int *nr_checkouts)
{
struct cache_entry *ce = active_cache[pos];
const char *path = ce->name;
ce = make_transient_cache_entry(mode, &oid, path, 2);
if (!ce)
die(_("make_cache_entry failed for path '%s'"), path);
- status = checkout_entry(ce, state, NULL);
+ status = checkout_entry(ce, state, NULL, nr_checkouts);
discard_cache_entry(ce);
return status;
}
struct commit *head;
int errs = 0;
struct lock_file lock_file = LOCK_INIT;
+ int nr_checkouts = 0, nr_unmerged = 0;
if (opts->track != BRANCH_TRACK_UNSPECIFIED)
die(_("'%s' cannot be used with updating paths"), "--track");
return run_add_interactive(revision, "--patch=checkout",
&opts->pathspec);
- hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
+ repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR);
if (read_cache_preload(&opts->pathspec) < 0)
return error(_("index file corrupt"));
struct cache_entry *ce = active_cache[pos];
if (ce->ce_flags & CE_MATCHED) {
if (!ce_stage(ce)) {
- errs |= checkout_entry(ce, &state, NULL);
+ errs |= checkout_entry(ce, &state,
+ NULL, &nr_checkouts);
continue;
}
if (opts->writeout_stage)
- errs |= checkout_stage(opts->writeout_stage, ce, pos, &state);
+ errs |= checkout_stage(opts->writeout_stage,
+ ce, pos,
+ &state, &nr_checkouts);
else if (opts->merge)
- errs |= checkout_merged(pos, &state);
+ errs |= checkout_merged(pos, &state,
+ &nr_unmerged);
pos = skip_same_name(ce, pos) - 1;
}
}
- errs |= finish_delayed_checkout(&state);
+ errs |= finish_delayed_checkout(&state, &nr_checkouts);
+
+ if (opts->count_checkout_paths) {
+ if (nr_unmerged)
+ fprintf_ln(stderr, Q_("Recreated %d merge conflict",
+ "Recreated %d merge conflicts",
+ nr_unmerged),
+ nr_unmerged);
+ if (opts->source_tree)
+ fprintf_ln(stderr, Q_("Updated %d path from %s",
+ "Updated %d paths from %s",
+ nr_checkouts),
+ nr_checkouts,
+ find_unique_abbrev(&opts->source_tree->object.oid,
+ DEFAULT_ABBREV));
+ else if (!nr_unmerged || nr_checkouts)
+ fprintf_ln(stderr, Q_("Updated %d path from the index",
+ "Updated %d paths from the index",
+ nr_checkouts),
+ nr_checkouts);
+ }
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));
* Remaining variables are not checkout options but used to track state
*/
+ /*
+ * Do the merge if this is the initial checkout. We cannot use
+ * is_cache_unborn() here because the index hasn't been loaded yet
+ * so cache_nr and timestamp.sec are always zero.
+ */
+ if (!file_exists(get_index_file()))
+ return 0;
+
return 1;
}
* a pain; plumb in an option to set
* o.renormalize?
*/
- init_merge_options(&o);
+ init_merge_options(&o, the_repository);
o.verbosity = 0;
work = write_tree_from_memory(&o);
free(refname);
}
else
- create_branch(opts->new_branch, new_branch_info->name,
+ create_branch(the_repository,
+ opts->new_branch, new_branch_info->name,
opts->new_branch_force ? 1 : 0,
opts->new_branch_force ? 1 : 0,
opts->new_branch_log,
delete_reflog(old_branch_info->path);
}
}
- remove_branch_state();
+ remove_branch_state(the_repository);
strbuf_release(&msg);
if (!opts->quiet &&
(new_branch_info->path || (!opts->force_detach && !strcmp(new_branch_info->name, "HEAD"))))
has_dash_dash = 1; /* case (3) or (1) */
else if (dash_dash_pos >= 2)
die(_("only one reference expected, %d given."), dash_dash_pos);
+ opts->count_checkout_paths = !opts->quiet && !has_dash_dash;
if (!strcmp(arg, "-"))
arg = "@{-1}";
*/
int recover_with_dwim = dwim_new_local_branch_ok;
- if (!has_dash_dash &&
- (check_filename(opts->prefix, arg) || !no_wildcard(arg)))
+ int could_be_checkout_paths = !has_dash_dash &&
+ check_filename(opts->prefix, arg);
+
+ if (!has_dash_dash && !no_wildcard(arg))
recover_with_dwim = 0;
+
/*
* Accept "git checkout foo" and "git checkout foo --"
* as candidates for dwim.
const char *remote = unique_tracking_name(arg, rev,
dwim_remotes_matched);
if (remote) {
+ if (could_be_checkout_paths)
+ die(_("'%s' could be both a local file and a tracking branch.\n"
+ "Please use -- (and optionally --no-guess) to disambiguate"),
+ arg);
*new_branch = arg;
arg = remote;
/* DWIMmed to create local branch, case (3).(b) */
struct checkout_opts opts;
struct branch_info new_branch_info;
char *conflict_style = NULL;
- int dwim_new_local_branch = 1;
+ int dwim_new_local_branch, no_dwim_new_local_branch = 0;
int dwim_remotes_matched = 0;
struct option options[] = {
OPT__QUIET(&opts.quiet, N_("suppress progress reporting")),
OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree,
N_("do not limit pathspecs to sparse entries only")),
- OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
- N_("second guess 'git checkout <no-such-branch>'")),
+ OPT_BOOL(0, "no-guess", &no_dwim_new_local_branch,
+ N_("do not second guess 'git checkout <no-such-branch>'")),
OPT_BOOL(0, "ignore-other-worktrees", &opts.ignore_other_worktrees,
N_("do not check if another worktree is holding the given ref")),
{ OPTION_CALLBACK, 0, "recurse-submodules", NULL,
argc = parse_options(argc, argv, prefix, options, checkout_usage,
PARSE_OPT_KEEP_DASHDASH);
+ dwim_new_local_branch = !no_dwim_new_local_branch;
if (opts.show_progress < 0) {
if (opts.quiet)
opts.show_progress = 0;
* Based on git-clean.sh by Pavel Roskin
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "cache.h"
#include "config.h"
* Clone a repository into a different directory that does not yet exist.
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "builtin.h"
#include "config.h"
#include "lockfile.h"
}
static struct ref *wanted_peer_refs(const struct ref *refs,
- struct refspec_item *refspec)
+ struct refspec *refspec)
{
struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
struct ref *local_refs = head;
warning(_("Could not find remote branch %s to clone."),
option_branch);
else {
- get_fetch_map(remote_head, refspec, &tail, 0);
+ int i;
+ for (i = 0; i < refspec->nr; i++)
+ get_fetch_map(remote_head, &refspec->items[i],
+ &tail, 0);
/* if --branch=tag, pull the requested tag explicitly */
get_fetch_map(remote_head, tag_refspec, &tail, 0);
}
- } else
- get_fetch_map(refs, refspec, &tail, 0);
+ } else {
+ int i;
+ for (i = 0; i < refspec->nr; i++)
+ get_fetch_map(refs, &refspec->items[i], &tail, 0);
+ }
if (!option_mirror && !option_single_branch && !option_no_tags)
get_fetch_map(refs, tag_refspec, &tail, 0);
const struct ref *our_head_points_at;
struct ref *mapped_refs;
const struct ref *ref;
- struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
+ struct strbuf key = STRBUF_INIT;
+ struct strbuf default_refspec = STRBUF_INIT;
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
struct transport *transport = NULL;
const char *src_ref_prefix = "refs/heads/";
int err = 0, complete_refs_before_fetch = 1;
int submodule_progress;
- struct refspec rs = REFSPEC_INIT_FETCH;
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
fetch_if_missing = 0;
strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin);
}
- strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
strbuf_addf(&key, "remote.%s.url", option_origin);
git_config_set(key.buf, repo);
strbuf_reset(&key);
if (option_required_reference.nr || option_optional_reference.nr)
setup_reference();
- refspec_append(&rs, value.buf);
+ remote = remote_get(option_origin);
- strbuf_reset(&value);
+ strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
+ branch_top.buf);
+ refspec_append(&remote->fetch, default_refspec.buf);
- remote = remote_get(option_origin);
transport = transport_get(remote, remote->url[0]);
transport_set_verbosity(transport, option_verbosity, option_progress);
transport->family = family;
option_upload_pack);
if (filter_options.choice) {
+ struct strbuf expanded_filter_spec = STRBUF_INIT;
+ expand_list_objects_filter_spec(&filter_options,
+ &expanded_filter_spec);
transport_set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
- filter_options.filter_spec);
+ expanded_filter_spec.buf);
transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
+ strbuf_release(&expanded_filter_spec);
}
if (transport->smart_options && !deepen && !filter_options.choice)
argv_array_push(&ref_prefixes, "HEAD");
- refspec_ref_prefixes(&rs, &ref_prefixes);
+ refspec_ref_prefixes(&remote->fetch, &ref_prefixes);
if (option_branch)
expand_ref_prefix(&ref_prefixes, option_branch);
if (!option_no_tags)
refs = transport_get_remote_refs(transport, &ref_prefixes);
if (refs) {
- &