diff options
Diffstat (limited to 'Documentation')
339 files changed, 19004 insertions, 5969 deletions
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index f45db5b727..711cb9171e 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -75,7 +75,7 @@ For shell scripts specifically (not exhaustive): - If you want to find out if a command is available on the user's $PATH, you should use 'type <command>', instead of 'which <command>'. - The output of 'which' is not machine parseable and its exit code + The output of 'which' is not machine parsable and its exit code is not reliable across platforms. - We use POSIX compliant parameter substitutions and avoid bashisms; @@ -91,16 +91,10 @@ For shell scripts specifically (not exhaustive): - No shell arrays. - - No strlen ${#parameter}. - - No pattern replacement ${parameter/pattern/string}. - We use Arithmetic Expansion $(( ... )). - - Inside Arithmetic Expansion, spell shell variables with $ in front - of them, as some shells do not grok $((x)) while accepting $(($x)) - just fine (e.g. dash older than 0.5.4). - - We do not use Process Substitution <(list) or >(list). - Do not write control structures on a single line with semicolon. @@ -181,6 +175,11 @@ For shell scripts specifically (not exhaustive): does not have such a problem. + - Even though "local" is not part of POSIX, we make heavy use of it + in our test suite. We do not use it in scripted Porcelains, and + hopefully nobody starts using "local" before they are reimplemented + in C ;-) + For C programs: @@ -203,7 +202,7 @@ For C programs: . since early 2012 with e1327023ea, we have been using an enum definition whose last element is followed by a comma. This, like an array initializer that ends with a trailing comma, can be used - to reduce the patch noise when adding a new identifer at the end. + to reduce the patch noise when adding a new identifier at the end. . since mid 2017 with cbc0f81d, we have been using designated initializers for struct (e.g. "struct t v = { .val = 'a' };"). @@ -238,6 +237,18 @@ For C programs: while( condition ) func (bar+1); + - Do not explicitly compare an integral value with constant 0 or '\0', + or a pointer value with constant NULL. For instance, to validate that + counted array <ptr, cnt> is initialized but has no elements, write: + + if (!ptr || cnt) + BUG("empty array expected"); + + and not: + + if (ptr == NULL || cnt != 0); + BUG("empty array expected"); + - We avoid using braces unnecessarily. I.e. if (bla) { @@ -483,21 +494,21 @@ For Python scripts: - We follow PEP-8 (http://www.python.org/dev/peps/pep-0008/). - - As a minimum, we aim to be compatible with Python 2.6 and 2.7. + - As a minimum, we aim to be compatible with Python 2.7. - Where required libraries do not restrict us to Python 2, we try to also be compatible with Python 3.1 and later. - - When you must differentiate between Unicode literals and byte string - literals, it is OK to use the 'b' prefix. Even though the Python - documentation for version 2.6 does not mention this prefix, it has - been supported since version 2.6.0. - Error Messages - Do not end error messages with a full stop. - - Do not capitalize ("unable to open %s", not "Unable to open %s") + - Do not capitalize the first word, only because it is the first word + in the message ("unable to open %s", not "Unable to open %s"). But + "SHA-3 not supported" is fine, because the reason the first word is + capitalized is not because it is at the beginning of the sentence, + but because the word would be spelled in capital letters even when + it appeared in the middle of the sentence. - Say what the error is first ("cannot open %s", not "%s: cannot open") @@ -540,6 +551,51 @@ Writing Documentation: documentation, please see the documentation-related advice in the Documentation/SubmittingPatches file). + In order to ensure the documentation is inclusive, avoid assuming + that an unspecified example person is male or female, and think + twice before using "he", "him", "she", or "her". Here are some + tips to avoid use of gendered pronouns: + + - Prefer succinctness and matter-of-factly describing functionality + in the abstract. E.g. + + --short:: Emit output in the short-format. + + and avoid something like these overly verbose alternatives: + + --short:: Use this to emit output in the short-format. + --short:: You can use this to get output in the short-format. + --short:: A user who prefers shorter output could.... + --short:: Should a person and/or program want shorter output, he + she/they/it can... + + This practice often eliminates the need to involve human actors in + your description, but it is a good practice regardless of the + avoidance of gendered pronouns. + + - When it becomes awkward to stick to this style, prefer "you" when + addressing the the hypothetical user, and possibly "we" when + discussing how the program might react to the user. E.g. + + You can use this option instead of --xyz, but we might remove + support for it in future versions. + + while keeping in mind that you can probably be less verbose, e.g. + + Use this instead of --xyz. This option might be removed in future + versions. + + - If you still need to refer to an example person that is + third-person singular, you may resort to "singular they" to avoid + "he/she/him/her", e.g. + + A contributor asks their upstream to pull from them. + + Note that this sounds ungrammatical and unnatural to those who + learned that "they" is only used for third-person plural, e.g. + those who learn English as a second language in some parts of the + world. + Every user-visible change should be reflected in the documentation. The same general rule as for code applies -- imitate the existing conventions. diff --git a/Documentation/Makefile b/Documentation/Makefile index dbf5a0f276..f5605b7767 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -2,6 +2,8 @@ MAN1_TXT = MAN5_TXT = MAN7_TXT = +HOWTO_TXT = +DOC_DEP_TXT = TECH_DOCS = ARTICLES = SP_ARTICLES = @@ -17,9 +19,11 @@ MAN1_TXT += git.txt MAN1_TXT += gitk.txt MAN1_TXT += gitweb.txt +# man5 / man7 guides (note: new guides should also be added to command-list.txt) MAN5_TXT += gitattributes.txt MAN5_TXT += githooks.txt MAN5_TXT += gitignore.txt +MAN5_TXT += gitmailmap.txt MAN5_TXT += gitmodules.txt MAN5_TXT += gitrepository-layout.txt MAN5_TXT += gitweb.conf.txt @@ -30,6 +34,7 @@ MAN7_TXT += gitcredentials.txt MAN7_TXT += gitcvs-migration.txt MAN7_TXT += gitdiffcore.txt MAN7_TXT += giteveryday.txt +MAN7_TXT += gitfaq.txt MAN7_TXT += gitglossary.txt MAN7_TXT += gitnamespaces.txt MAN7_TXT += gitremote-helpers.txt @@ -39,6 +44,11 @@ MAN7_TXT += gittutorial-2.txt MAN7_TXT += gittutorial.txt MAN7_TXT += gitworkflows.txt +HOWTO_TXT += $(wildcard howto/*.txt) + +DOC_DEP_TXT += $(wildcard *.txt) +DOC_DEP_TXT += $(wildcard config/*.txt) + ifdef MAN_FILTER MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)) else @@ -73,9 +83,12 @@ SP_ARTICLES += howto/rebuild-from-update-hook SP_ARTICLES += howto/rebase-from-internal-branch SP_ARTICLES += howto/keep-canonical-history-correct SP_ARTICLES += howto/maintain-git +SP_ARTICLES += howto/coordinate-embargoed-releases API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) SP_ARTICLES += $(API_DOCS) +TECH_DOCS += MyFirstContribution +TECH_DOCS += MyFirstObjectWalk TECH_DOCS += SubmittingPatches TECH_DOCS += technical/hash-function-transition TECH_DOCS += technical/http-protocol @@ -85,11 +98,13 @@ TECH_DOCS += technical/multi-pack-index TECH_DOCS += technical/pack-format TECH_DOCS += technical/pack-heuristics TECH_DOCS += technical/pack-protocol +TECH_DOCS += technical/parallel-checkout TECH_DOCS += technical/partial-clone TECH_DOCS += technical/protocol-capabilities TECH_DOCS += technical/protocol-common TECH_DOCS += technical/protocol-v2 TECH_DOCS += technical/racy-git +TECH_DOCS += technical/reftable TECH_DOCS += technical/send-pack-pipeline TECH_DOCS += technical/shallow TECH_DOCS += technical/signature-format @@ -122,7 +137,9 @@ ASCIIDOC_HTML = xhtml11 ASCIIDOC_DOCBOOK = docbook ASCIIDOC_CONF = -f asciidoc.conf ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA) $(ASCIIDOC_CONF) \ - -agit_version=$(GIT_VERSION) + -amanversion=$(GIT_VERSION) \ + -amanmanual='Git Manual' -amansource='Git' +ASCIIDOC_DEPS = asciidoc.conf GIT-ASCIIDOCFLAGS TXT_TO_HTML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_HTML) TXT_TO_XML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_DOCBOOK) MANPAGE_XSL = manpage-normal.xsl @@ -146,32 +163,9 @@ endif -include ../config.mak.autogen -include ../config.mak -# -# For docbook-xsl ... -# -1.68.1, no extra settings are needed? -# 1.69.0, set ASCIIDOC_ROFF? -# 1.69.1-1.71.0, set DOCBOOK_SUPPRESS_SP? -# 1.71.1, set ASCIIDOC_ROFF? -# 1.72.0, set DOCBOOK_XSL_172. -# 1.73.0-, no extra settings are needed -# - -ifdef DOCBOOK_XSL_172 -ASCIIDOC_EXTRA += -a git-asciidoc-no-roff -MANPAGE_XSL = manpage-1.72.xsl -else - ifndef ASCIIDOC_ROFF - # docbook-xsl after 1.72 needs the regular XSL, but will not - # pass-thru raw roff codes from asciidoc.conf, so turn them off. - ASCIIDOC_EXTRA += -a git-asciidoc-no-roff - endif -endif ifndef NO_MAN_BOLD_LITERAL XMLTO_EXTRA += -m manpage-bold-literal.xsl endif -ifdef DOCBOOK_SUPPRESS_SP -XMLTO_EXTRA += -m manpage-suppress-sp.xsl -endif # Newer DocBook stylesheet emits warning cruft in the output when # this is not set, and if set it shows an absolute link. Older @@ -196,11 +190,14 @@ ifdef USE_ASCIIDOCTOR ASCIIDOC = asciidoctor ASCIIDOC_CONF = ASCIIDOC_HTML = xhtml5 -ASCIIDOC_DOCBOOK = docbook45 +ASCIIDOC_DOCBOOK = docbook5 ASCIIDOC_EXTRA += -acompat-mode -atabsize=8 ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;' +ASCIIDOC_DEPS = asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS DBLATEX_COMMON = +XMLTO_EXTRA += --skip-validation +XMLTO_EXTRA += -x manpage.xsl endif SHELL_PATH ?= $(SHELL) @@ -287,7 +284,9 @@ install-html: html ../GIT-VERSION-FILE: FORCE $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE +ifneq ($(MAKECMDGOALS),clean) -include ../GIT-VERSION-FILE +endif # # Determine "include::" file references in asciidoc files. @@ -296,12 +295,12 @@ docdep_prereqs = \ mergetools-list.made $(mergetools_txt) \ cmd-list.made $(cmds_txt) -doc.dep : $(docdep_prereqs) $(wildcard *.txt) $(wildcard config/*.txt) build-docdep.perl - $(QUIET_GEN)$(RM) $@+ $@ && \ - $(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \ - mv $@+ $@ +doc.dep : $(docdep_prereqs) $(DOC_DEP_TXT) build-docdep.perl + $(QUIET_GEN)$(PERL_PATH) ./build-docdep.perl >$@ $(QUIET_STDERR) +ifneq ($(MAKECMDGOALS),clean) -include doc.dep +endif cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-ancillarymanipulators.txt \ @@ -310,14 +309,14 @@ cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-plumbingmanipulators.txt \ cmds-synchingrepositories.txt \ cmds-synchelpers.txt \ + cmds-guide.txt \ cmds-purehelpers.txt \ cmds-foreignscminterface.txt $(cmds_txt): cmd-list.made cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) - $(QUIET_GEN)$(RM) $@ && \ - $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \ + $(QUIET_GEN)$(PERL_PATH) ./cmd-list.perl ../command-list.txt $(cmds_txt) $(QUIET_STDERR) && \ date >$@ mergetools_txt = mergetools-diff.txt mergetools-merge.txt @@ -325,7 +324,7 @@ mergetools_txt = mergetools-diff.txt mergetools-merge.txt $(mergetools_txt): mergetools-list.made mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*) - $(QUIET_GEN)$(RM) $@ && \ + $(QUIET_GEN) \ $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && \ . ../git-mergetool--lib.sh && \ show_tool_names can_diff "* " || :' >mergetools-diff.txt && \ @@ -354,32 +353,23 @@ clean: $(RM) manpage-base-url.xsl $(RM) GIT-ASCIIDOCFLAGS -$(MAN_HTML): %.html : %.txt asciidoc.conf asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(TXT_TO_HTML) -d manpage -o $@+ $< && \ - mv $@+ $@ +$(MAN_HTML): %.html : %.txt $(ASCIIDOC_DEPS) + $(QUIET_ASCIIDOC)$(TXT_TO_HTML) -d manpage -o $@ $< -$(OBSOLETE_HTML): %.html : %.txto asciidoc.conf asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(TXT_TO_HTML) -o $@+ $< && \ - mv $@+ $@ +$(OBSOLETE_HTML): %.html : %.txto $(ASCIIDOC_DEPS) + $(QUIET_ASCIIDOC)$(TXT_TO_HTML) -o $@ $< manpage-base-url.xsl: manpage-base-url.xsl.in $(QUIET_GEN)sed "s|@@MAN_BASE_URL@@|$(MAN_BASE_URL)|" $< > $@ %.1 %.5 %.7 : %.xml manpage-base-url.xsl $(wildcard manpage*.xsl) - $(QUIET_XMLTO)$(RM) $@ && \ - $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< + $(QUIET_XMLTO)$(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< -%.xml : %.txt asciidoc.conf asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(TXT_TO_XML) -d manpage -o $@+ $< && \ - mv $@+ $@ +%.xml : %.txt $(ASCIIDOC_DEPS) + $(QUIET_ASCIIDOC)$(TXT_TO_XML) -d manpage -o $@ $< user-manual.xml: user-manual.txt user-manual.conf asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ - $(TXT_TO_XML) -d book -o $@+ $< && \ - mv $@+ $@ + $(QUIET_ASCIIDOC)$(TXT_TO_XML) -d book -o $@ $< technical/api-index.txt: technical/api-index-skel.txt \ technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS)) @@ -394,49 +384,41 @@ SubmittingPatches.txt: SubmittingPatches $(QUIET_GEN) cp $< $@ XSLT = docbook.xsl -XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css +XSLTOPTS = +XSLTOPTS += --xinclude +XSLTOPTS += --stringparam html.stylesheet docbook-xsl.css +XSLTOPTS += --param generate.consistent.ids 1 user-manual.html: user-manual.xml $(XSLT) - $(QUIET_XSLTPROC)$(RM) $@+ $@ && \ - xsltproc $(XSLTOPTS) -o $@+ $(XSLT) $< && \ - mv $@+ $@ + $(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $< git.info: user-manual.texi $(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi user-manual.texi: user-manual.xml - $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ - $(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \ - $(PERL_PATH) fix-texi.perl <$@++ >$@+ && \ - rm $@++ && \ - mv $@+ $@ + $(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@+ && \ + $(PERL_PATH) fix-texi.perl <$@+ >$@ && \ + $(RM) $@+ user-manual.pdf: user-manual.xml - $(QUIET_DBLATEX)$(RM) $@+ $@ && \ - $(DBLATEX) -o $@+ $(DBLATEX_COMMON) $< && \ - mv $@+ $@ + $(QUIET_DBLATEX)$(DBLATEX) -o $@ $(DBLATEX_COMMON) $< gitman.texi: $(MAN_XML) cat-texi.perl texi.xsl - $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ + $(QUIET_DB2TEXI) \ ($(foreach xml,$(sort $(MAN_XML)),xsltproc -o $(xml)+ texi.xsl $(xml) && \ $(DOCBOOK2X_TEXI) --encoding=UTF-8 --to-stdout $(xml)+ && \ - rm $(xml)+ &&) true) > $@++ && \ - $(PERL_PATH) cat-texi.perl $@ <$@++ >$@+ && \ - rm $@++ && \ - mv $@+ $@ + $(RM) $(xml)+ &&) true) > $@+ && \ + $(PERL_PATH) cat-texi.perl $@ <$@+ >$@ && \ + $(RM) $@+ gitman.info: gitman.texi $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml - $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ - $(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+ && \ - mv $@+ $@ + $(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@ -howto-index.txt: howto-index.sh $(wildcard howto/*.txt) - $(QUIET_GEN)$(RM) $@+ $@ && \ - '$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(wildcard howto/*.txt)) >$@+ && \ - mv $@+ $@ +howto-index.txt: howto-index.sh $(HOWTO_TXT) + $(QUIET_GEN)'$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(HOWTO_TXT)) >$@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt @@ -444,11 +426,10 @@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt WEBDOC_DEST = /pub/software/scm/git/docs howto/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ -$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ +$(patsubst %.txt,%.html,$(HOWTO_TXT)): %.html : %.txt GIT-ASCIIDOCFLAGS + $(QUIET_ASCIIDOC) \ sed -e '1,/^$$/d' $< | \ - $(TXT_TO_HTML) - >$@+ && \ - mv $@+ $@ + $(TXT_TO_HTML) - >$@ install-webdoc : html '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(WEBDOC_DEST) @@ -476,11 +457,20 @@ print-man1: @for i in $(MAN1_TXT); do echo $$i; done lint-docs:: - $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl + $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl \ + $(HOWTO_TXT) $(DOC_DEP_TXT) \ + --section=1 $(MAN1_TXT) \ + --section=5 $(MAN5_TXT) \ + --section=7 $(MAN7_TXT); \ + $(PERL_PATH) lint-man-end-blurb.perl $(MAN_TXT); \ + $(PERL_PATH) lint-man-section-order.perl $(MAN_TXT); ifeq ($(wildcard po/Makefile),po/Makefile) doc-l10n install-l10n:: $(MAKE) -C po $@ endif +# Delete the target file on error +.DELETE_ON_ERROR: + .PHONY: FORCE diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.txt new file mode 100644 index 0000000000..015cf24631 --- /dev/null +++ b/Documentation/MyFirstContribution.txt @@ -0,0 +1,1232 @@ +My First Contribution to the Git Project +======================================== +:sectanchors: + +[[summary]] +== Summary + +This is a tutorial demonstrating the end-to-end workflow of creating a change to +the Git tree, sending it for review, and making changes based on comments. + +[[prerequisites]] +=== Prerequisites + +This tutorial assumes you're already fairly familiar with using Git to manage +source code. The Git workflow steps will largely remain unexplained. + +[[related-reading]] +=== Related Reading + +This tutorial aims to summarize the following documents, but the reader may find +useful additional context: + +- `Documentation/SubmittingPatches` +- `Documentation/howto/new-command.txt` + +[[getting-help]] +=== Getting Help + +If you get stuck, you can seek help in the following places. + +==== git@vger.kernel.org + +This is the main Git project mailing list where code reviews, version +announcements, design discussions, and more take place. Those interested in +contributing are welcome to post questions here. The Git list requires +plain-text-only emails and prefers inline and bottom-posting when replying to +mail; you will be CC'd in all replies to you. Optionally, you can subscribe to +the list by sending an email to majordomo@vger.kernel.org with "subscribe git" +in the body. The https://lore.kernel.org/git[archive] of this mailing list is +available to view in a browser. + +==== https://groups.google.com/forum/#!forum/git-mentoring[git-mentoring@googlegroups.com] + +This mailing list is targeted to new contributors and was created as a place to +post questions and receive answers outside of the public eye of the main list. +Veteran contributors who are especially interested in helping mentor newcomers +are present on the list. In order to avoid search indexers, group membership is +required to view messages; anyone can join and no approval is required. + +==== https://web.libera.chat/#git-devel[#git-devel] on Libera Chat + +This IRC channel is for conversations between Git contributors. If someone is +currently online and knows the answer to your question, you can receive help +in real time. Otherwise, you can read the +https://colabti.org/irclogger/irclogger_logs/git-devel[scrollback] to see +whether someone answered you. IRC does not allow offline private messaging, so +if you try to private message someone and then log out of IRC, they cannot +respond to you. It's better to ask your questions in the channel so that you +can be answered if you disconnect and so that others can learn from the +conversation. + +[[getting-started]] +== Getting Started + +[[cloning]] +=== Clone the Git Repository + +Git is mirrored in a number of locations. Clone the repository from one of them; +https://git-scm.com/downloads suggests one of the best places to clone from is +the mirror on GitHub. + +---- +$ git clone https://github.com/git/git git +$ cd git +---- + +[[dependencies]] +=== Installing Dependencies + +To build Git from source, you need to have a handful of dependencies installed +on your system. For a hint of what's needed, you can take a look at +`INSTALL`, paying close attention to the section about Git's dependencies on +external programs and libraries. That document mentions a way to "test-drive" +our freshly built Git without installing; that's the method we'll be using in +this tutorial. + +Make sure that your environment has everything you need by building your brand +new clone of Git from the above step: + +---- +$ make +---- + +NOTE: The Git build is parallelizable. `-j#` is not included above but you can +use it as you prefer, here and elsewhere. + +[[identify-problem]] +=== Identify Problem to Solve + +//// +Use + to indicate fixed-width here; couldn't get ` to work nicely with the +quotes around "Pony Saying 'Um, Hello'". +//// +In this tutorial, we will add a new command, +git psuh+, short for ``Pony Saying +`Um, Hello''' - a feature which has gone unimplemented despite a high frequency +of invocation during users' typical daily workflow. + +(We've seen some other effort in this space with the implementation of popular +commands such as `sl`.) + +[[setup-workspace]] +=== Set Up Your Workspace + +Let's start by making a development branch to work on our changes. Per +`Documentation/SubmittingPatches`, since a brand new command is a new feature, +it's fine to base your work on `master`. However, in the future for bugfixes, +etc., you should check that document and base it on the appropriate branch. + +For the purposes of this document, we will base all our work on the `master` +branch of the upstream project. Create the `psuh` branch you will use for +development like so: + +---- +$ git checkout -b psuh origin/master +---- + +We'll make a number of commits here in order to demonstrate how to send a topic +with multiple patches up for review simultaneously. + +[[code-it-up]] +== Code It Up! + +NOTE: A reference implementation can be found at +https://github.com/nasamuffin/git/tree/psuh. + +[[add-new-command]] +=== Adding a New Command + +Lots of the subcommands are written as builtins, which means they are +implemented in C and compiled into the main `git` executable. Implementing the +very simple `psuh` command as a built-in will demonstrate the structure of the +codebase, the internal API, and the process of working together as a contributor +with the reviewers and maintainer to integrate this change into the system. + +Built-in subcommands are typically implemented in a function named "cmd_" +followed by the name of the subcommand, in a source file named after the +subcommand and contained within `builtin/`. So it makes sense to implement your +command in `builtin/psuh.c`. Create that file, and within it, write the entry +point for your command in a function matching the style and signature: + +---- +int cmd_psuh(int argc, const char **argv, const char *prefix) +---- + +We'll also need to add the declaration of psuh; open up `builtin.h`, find the +declaration for `cmd_pull`, and add a new line for `psuh` immediately before it, +in order to keep the declarations alphabetically sorted: + +---- +int cmd_psuh(int argc, const char **argv, const char *prefix); +---- + +Be sure to `#include "builtin.h"` in your `psuh.c`. + +Go ahead and add some throwaway printf to that function. This is a decent +starting point as we can now add build rules and register the command. + +NOTE: Your throwaway text, as well as much of the text you will be adding over +the course of this tutorial, is user-facing. That means it needs to be +localizable. Take a look at `po/README` under "Marking strings for translation". +Throughout the tutorial, we will mark strings for translation as necessary; you +should also do so when writing your user-facing commands in the future. + +---- +int cmd_psuh(int argc, const char **argv, const char *prefix) +{ + printf(_("Pony saying hello goes here.\n")); + return 0; +} +---- + +Let's try to build it. Open `Makefile`, find where `builtin/pull.o` is added +to `BUILTIN_OBJS`, and add `builtin/psuh.o` in the same way next to it in +alphabetical order. Once you've done so, move to the top-level directory and +build simply with `make`. Also add the `DEVELOPER=1` variable to turn on +some additional warnings: + +---- +$ echo DEVELOPER=1 >config.mak +$ make +---- + +NOTE: When you are developing the Git project, it's preferred that you use the +`DEVELOPER` flag; if there's some reason it doesn't work for you, you can turn +it off, but it's a good idea to mention the problem to the mailing list. + +Great, now your new command builds happily on its own. But nobody invokes it. +Let's change that. + +The list of commands lives in `git.c`. We can register a new command by adding +a `cmd_struct` to the `commands[]` array. `struct cmd_struct` takes a string +with the command name, a function pointer to the command implementation, and a +setup option flag. For now, let's keep mimicking `push`. Find the line where +`cmd_push` is registered, copy it, and modify it for `cmd_psuh`, placing the new +line in alphabetical order (immediately before `cmd_pull`). + +The options are documented in `builtin.h` under "Adding a new built-in." Since +we hope to print some data about the user's current workspace context later, +we need a Git directory, so choose `RUN_SETUP` as your only option. + +Go ahead and build again. You should see a clean build, so let's kick the tires +and see if it works. There's a binary you can use to test with in the +`bin-wrappers` directory. + +---- +$ ./bin-wrappers/git psuh +---- + +Check it out! You've got a command! Nice work! Let's commit this. + +`git status` reveals modified `Makefile`, `builtin.h`, and `git.c` as well as +untracked `builtin/psuh.c` and `git-psuh`. First, let's take care of the binary, +which should be ignored. Open `.gitignore` in your editor, find `/git-pull`, and +add an entry for your new command in alphabetical order: + +---- +... +/git-prune-packed +/git-psuh +/git-pull +/git-push +/git-quiltimport +/git-range-diff +... +---- + +Checking `git status` again should show that `git-psuh` has been removed from +the untracked list and `.gitignore` has been added to the modified list. Now we +can stage and commit: + +---- +$ git add Makefile builtin.h builtin/psuh.c git.c .gitignore +$ git commit -s +---- + +You will be presented with your editor in order to write a commit message. Start +the commit with a 50-column or less subject line, including the name of the +component you're working on, followed by a blank line (always required) and then +the body of your commit message, which should provide the bulk of the context. +Remember to be explicit and provide the "Why" of your change, especially if it +couldn't easily be understood from your diff. When editing your commit message, +don't remove the `Signed-off-by` trailer which was added by `-s` above. + +---- +psuh: add a built-in by popular demand + +Internal metrics indicate this is a command many users expect to be +present. So here's an implementation to help drive customer +satisfaction and engagement: a pony which doubtfully greets the user, +or, a Pony Saying "Um, Hello" (PSUH). + +This commit message is intentionally formatted to 72 columns per line, +starts with a single line as "commit message subject" that is written as +if to command the codebase to do something (add this, teach a command +that). The body of the message is designed to add information about the +commit that is not readily deduced from reading the associated diff, +such as answering the question "why?". + +Signed-off-by: A U Thor <author@example.com> +---- + +Go ahead and inspect your new commit with `git show`. "psuh:" indicates you +have modified mainly the `psuh` command. The subject line gives readers an idea +of what you've changed. The sign-off line (`-s`) indicates that you agree to +the Developer's Certificate of Origin 1.1 (see the +`Documentation/SubmittingPatches` +++[[dco]]+++ header). + +For the remainder of the tutorial, the subject line only will be listed for the +sake of brevity. However, fully-fleshed example commit messages are available +on the reference implementation linked at the top of this document. + +[[implementation]] +=== Implementation + +It's probably useful to do at least something besides printing out a string. +Let's start by having a look at everything we get. + +Modify your `cmd_psuh` implementation to dump the args you're passed, keeping +existing `printf()` calls in place: + +---- + int i; + + ... + + printf(Q_("Your args (there is %d):\n", + "Your args (there are %d):\n", + argc), + argc); + for (i = 0; i < argc; i++) + printf("%d: %s\n", i, argv[i]); + + printf(_("Your current working directory:\n<top-level>%s%s\n"), + prefix ? "/" : "", prefix ? prefix : ""); + +---- + +Build and try it. As you may expect, there's pretty much just whatever we give +on the command line, including the name of our command. (If `prefix` is empty +for you, try `cd Documentation/ && ../bin-wrappers/git psuh`). That's not so +helpful. So what other context can we get? + +Add a line to `#include "config.h"`. Then, add the following bits to the +function body: + +---- + const char *cfg_name; + +... + + git_config(git_default_config, NULL); + if (git_config_get_string_tmp("user.name", &cfg_name) > 0) + printf(_("No name is found in config\n")); + else + printf(_("Your name: %s\n"), cfg_name); +---- + +`git_config()` will grab the configuration from config files known to Git and +apply standard precedence rules. `git_config_get_string_tmp()` will look up +a specific key ("user.name") and give you the value. There are a number of +single-key lookup functions like this one; you can see them all (and more info +about how to use `git_config()`) in `Documentation/technical/api-config.txt`. + +You should see that the name printed matches the one you see when you run: + +---- +$ git config --get user.name +---- + +Great! Now we know how to check for values in the Git config. Let's commit this +too, so we don't lose our progress. + +---- +$ git add builtin/psuh.c +$ git commit -sm "psuh: show parameters & config opts" +---- + +NOTE: Again, the above is for sake of brevity in this tutorial. In a real change +you should not use `-m` but instead use the editor to write a meaningful +message. + +Still, it'd be nice to know what the user's working context is like. Let's see +if we can print the name of the user's current branch. We can mimic the +`git status` implementation; the printer is located in `wt-status.c` and we can +see that the branch is held in a `struct wt_status`. + +`wt_status_print()` gets invoked by `cmd_status()` in `builtin/commit.c`. +Looking at that implementation we see the status config being populated like so: + +---- +status_init_config(&s, git_status_config); +---- + +But as we drill down, we can find that `status_init_config()` wraps a call +to `git_config()`. Let's modify the code we wrote in the previous commit. + +Be sure to include the header to allow you to use `struct wt_status`: +---- +#include "wt-status.h" +---- + +Then modify your `cmd_psuh` implementation to declare your `struct wt_status`, +prepare it, and print its contents: + +---- + struct wt_status status; + +... + + wt_status_prepare(the_repository, &status); + git_config(git_default_config, &status); + +... + + printf(_("Your current branch: %s\n"), status.branch); +---- + +Run it again. Check it out - here's the (verbose) name of your current branch! + +Let's commit this as well. + +---- +$ git add builtin/psuh.c +$ git commit -sm "psuh: print the current branch" +---- + +Now let's see if we can get some info about a specific commit. + +Luckily, there are some helpers for us here. `commit.h` has a function called +`lookup_commit_reference_by_name` to which we can simply provide a hardcoded +string; `pretty.h` has an extremely handy `pp_commit_easy()` call which doesn't +require a full format object to be passed. + +Add the following includes: + +---- +#include "commit.h" +#include "pretty.h" +---- + +Then, add the following lines within your implementation of `cmd_psuh()` near +the declarations and the logic, respectively. + +---- + struct commit *c = NULL; + struct strbuf commitline = STRBUF_INIT; + +... + + c = lookup_commit_reference_by_name("origin/master"); + + if (c != NULL) { + pp_commit_easy(CMIT_FMT_ONELINE, c, &commitline); + printf(_("Current commit: %s\n"), commitline.buf); + } +---- + +The `struct strbuf` provides some safety belts to your basic `char*`, one of +which is a length member to prevent buffer overruns. It needs to be initialized +nicely with `STRBUF_INIT`. Keep it in mind when you need to pass around `char*`. + +`lookup_commit_reference_by_name` resolves the name you pass it, so you can play +with the value there and see what kind of things you can come up with. + +`pp_commit_easy` is a convenience wrapper in `pretty.h` that takes a single +format enum shorthand, rather than an entire format struct. It then +pretty-prints the commit according to that shorthand. These are similar to the +formats available with `--pretty=FOO` in many Git commands. + +Build it and run, and if you're using the same name in the example, you should +see the subject line of the most recent commit in `origin/master` that you know +about. Neat! Let's commit that as well. + +---- +$ git add builtin/psuh.c +$ git commit -sm "psuh: display the top of origin/master" +---- + +[[add-documentation]] +=== Adding Documentation + +Awesome! You've got a fantastic new command that you're ready to share with the +community. But hang on just a minute - this isn't very user-friendly. Run the +following: + +---- +$ ./bin-wrappers/git help psuh +---- + +Your new command is undocumented! Let's fix that. + +Take a look at `Documentation/git-*.txt`. These are the manpages for the +subcommands that Git knows about. You can open these up and take a look to get +acquainted with the format, but then go ahead and make a new file +`Documentation/git-psuh.txt`. Like with most of the documentation in the Git +project, help pages are written with AsciiDoc (see CodingGuidelines, "Writing +Documentation" section). Use the following template to fill out your own +manpage: + +// Surprisingly difficult to embed AsciiDoc source within AsciiDoc. +[listing] +.... +git-psuh(1) +=========== + +NAME +---- +git-psuh - Delight users' typo with a shy horse + + +SYNOPSIS +-------- +[verse] +'git-psuh [<arg>...]' + +DESCRIPTION +----------- +... + +OPTIONS[[OPTIONS]] +------------------ +... + +OUTPUT +------ +... + +GIT +--- +Part of the linkgit:git[1] suite +.... + +The most important pieces of this to note are the file header, underlined by =, +the NAME section, and the SYNOPSIS, which would normally contain the grammar if +your command took arguments. Try to use well-established manpage headers so your +documentation is consistent with other Git and UNIX manpages; this makes life +easier for your user, who can skip to the section they know contains the +information they need. + +NOTE: Before trying to build the docs, make sure you have the package `asciidoc` +installed. + +Now that you've written your manpage, you'll need to build it explicitly. We +convert your AsciiDoc to troff which is man-readable like so: + +---- +$ make all doc +$ man Documentation/git-psuh.1 +---- + +or + +---- +$ make -C Documentation/ git-psuh.1 +$ man Documentation/git-psuh.1 +---- + +While this isn't as satisfying as running through `git help`, you can at least +check that your help page looks right. + +You can also check that the documentation coverage is good (that is, the project +sees that your command has been implemented as well as documented) by running +`make check-docs` from the top-level. + +Go ahead and commit your new documentation change. + +[[add-usage]] +=== Adding Usage Text + +Try and run `./bin-wrappers/git psuh -h`. Your command should crash at the end. +That's because `-h` is a special case which your command should handle by +printing usage. + +Take a look at `Documentation/technical/api-parse-options.txt`. This is a handy +tool for pulling out options you need to be able to handle, and it takes a +usage string. + +In order to use it, we'll need to prepare a NULL-terminated array of usage +strings and a `builtin_psuh_options` array. + +Add a line to `#include "parse-options.h"`. + +At global scope, add your array of usage strings: + +---- +static const char * const psuh_usage[] = { + N_("git psuh [<arg>...]"), + NULL, +}; +---- + +Then, within your `cmd_psuh()` implementation, we can declare and populate our +`option` struct. Ours is pretty boring but you can add more to it if you want to +explore `parse_options()` in more detail: + +---- + struct option options[] = { + OPT_END() + }; +---- + +Finally, before you print your args and prefix, add the call to +`parse-options()`: + +---- + argc = parse_options(argc, argv, prefix, options, psuh_usage, 0); +---- + +This call will modify your `argv` parameter. It will strip the options you +specified in `options` from `argv` and the locations pointed to from `options` +entries will be updated. Be sure to replace your `argc` with the result from +`parse_options()`, or you will be confused if you try to parse `argv` later. + +It's worth noting the special argument `--`. As you may be aware, many Unix +commands use `--` to indicate "end of named parameters" - all parameters after +the `--` are interpreted merely as positional arguments. (This can be handy if +you want to pass as a parameter something which would usually be interpreted as +a flag.) `parse_options()` will terminate parsing when it reaches `--` and give +you the rest of the options afterwards, untouched. + +Now that you have a usage hint, you can teach Git how to show it in the general +command list shown by `git help git` or `git help -a`, which is generated from +`command-list.txt`. Find the line for 'git-pull' so you can add your 'git-psuh' +line above it in alphabetical order. Now, we can add some attributes about the +command which impacts where it shows up in the aforementioned help commands. The +top of `command-list.txt` shares some information about what each attribute +means; in those help pages, the commands are sorted according to these +attributes. `git psuh` is user-facing, or porcelain - so we will mark it as +"mainporcelain". For "mainporcelain" commands, the comments at the top of +`command-list.txt` indicate we can also optionally add an attribute from another +list; since `git psuh` shows some information about the user's workspace but +doesn't modify anything, let's mark it as "info". Make sure to keep your +attributes in the same style as the rest of `command-list.txt` using spaces to +align and delineate them: + +---- +git-prune-packed plumbingmanipulators +git-psuh mainporcelain info +git-pull mainporcelain remote +git-push mainporcelain remote +---- + +Build again. Now, when you run with `-h`, you should see your usage printed and +your command terminated before anything else interesting happens. Great! + +Go ahead and commit this one, too. + +[[testing]] +== Testing + +It's important to test your code - even for a little toy command like this one. +Moreover, your patch won't be accepted into the Git tree without tests. Your +tests should: + +* Illustrate the current behavior of the feature +* Prove the current behavior matches the expected behavior +* Ensure the externally-visible behavior isn't broken in later changes + +So let's write some tests. + +Related reading: `t/README` + +[[overview-test-structure]] +=== Overview of Testing Structure + +The tests in Git live in `t/` and are named with a 4-digit decimal number using +the schema shown in the Naming Tests section of `t/README`. + +[[write-new-test]] +=== Writing Your Test + +Since this a toy command, let's go ahead and name the test with t9999. However, +as many of the family/subcmd combinations are full, best practice seems to be +to find a command close enough to the one you've added and share its naming +space. + +Create a new file `t/t9999-psuh-tutorial.sh`. Begin with the header as so (see +"Writing Tests" and "Source 'test-lib.sh'" in `t/README`): + +---- +#!/bin/sh + +test_description='git-psuh test + +This test runs git-psuh and makes sure it does not crash.' + +. ./test-lib.sh +---- + +Tests are framed inside of a `test_expect_success` in order to output TAP +formatted results. Let's make sure that `git psuh` doesn't exit poorly and does +mention the right animal somewhere: + +---- +test_expect_success 'runs correctly with no args and good output' ' + git psuh >actual && + grep Pony actual +' +---- + +Indicate that you've run everything you wanted by adding the following at the +bottom of your script: + +---- +test_done +---- + +Make sure you mark your test script executable: + +---- +$ chmod +x t/t9999-psuh-tutorial.sh +---- + +You can get an idea of whether you created your new test script successfully +by running `make -C t test-lint`, which will check for things like test number +uniqueness, executable bit, and so on. + +[[local-test]] +=== Running Locally + +Let's try and run locally: + +---- +$ make +$ cd t/ && prove t9999-psuh-tutorial.sh +---- + +You can run the full test suite and ensure `git-psuh` didn't break anything: + +---- +$ cd t/ +$ prove -j$(nproc) --shuffle t[0-9]*.sh +---- + +NOTE: You can also do this with `make test` or use any testing harness which can +speak TAP. `prove` can run concurrently. `shuffle` randomizes the order the +tests are run in, which makes them resilient against unwanted inter-test +dependencies. `prove` also makes the output nicer. + +Go ahead and commit this change, as well. + +[[ready-to-share]] +== Getting Ready to Share + +You may have noticed already that the Git project performs its code reviews via +emailed patches, which are then applied by the maintainer when they are ready +and approved by the community. The Git project does not accept patches from +pull requests, and the patches emailed for review need to be formatted a +specific way. At this point the tutorial diverges, in order to demonstrate two +different methods of formatting your patchset and getting it reviewed. + +The first method to be covered is GitGitGadget, which is useful for those +already familiar with GitHub's common pull request workflow. This method +requires a GitHub account. + +The second method to be covered is `git send-email`, which can give slightly +more fine-grained control over the emails to be sent. This method requires some +setup which can change depending on your system and will not be covered in this +tutorial. + +Regardless of which method you choose, your engagement with reviewers will be +the same; the review process will be covered after the sections on GitGitGadget +and `git send-email`. + +[[howto-ggg]] +== Sending Patches via GitGitGadget + +One option for sending patches is to follow a typical pull request workflow and +send your patches out via GitGitGadget. GitGitGadget is a tool created by +Johannes Schindelin to make life as a Git contributor easier for those used to +the GitHub PR workflow. It allows contributors to open pull requests against its +mirror of the Git project, and does some magic to turn the PR into a set of +emails and send them out for you. It also runs the Git continuous integration +suite for you. It's documented at http://gitgitgadget.github.io. + +[[create-fork]] +=== Forking `git/git` on GitHub + +Before you can send your patch off to be reviewed using GitGitGadget, you will +need to fork the Git project and upload your changes. First thing - make sure +you have a GitHub account. + +Head to the https://github.com/git/git[GitHub mirror] and look for the Fork +button. Place your fork wherever you deem appropriate and create it. + +[[upload-to-fork]] +=== Uploading to Your Own Fork + +To upload your branch to your own fork, you'll need to add the new fork as a +remote. You can use `git remote -v` to show the remotes you have added already. +From your new fork's page on GitHub, you can press "Clone or download" to get +the URL; then you need to run the following to add, replacing your own URL and +remote name for the examples provided: + +---- +$ git remote add remotename git@github.com:remotename/git.git +---- + +or to use the HTTPS URL: + +---- +$ git remote add remotename https://github.com/remotename/git/.git +---- + +Run `git remote -v` again and you should see the new remote showing up. +`git fetch remotename` (with the real name of your remote replaced) in order to +get ready to push. + +Next, double-check that you've been doing all your development in a new branch +by running `git branch`. If you didn't, now is a good time to move your new +commits to their own branch. + +As mentioned briefly at the beginning of this document, we are basing our work +on `master`, so go ahead and update as shown below, or using your preferred +workflow. + +---- +$ git checkout master +$ git pull -r +$ git rebase master psuh +---- + +Finally, you're ready to push your new topic branch! (Due to our branch and +command name choices, be careful when you type the command below.) + +---- +$ git push remotename psuh +---- + +Now you should be able to go and check out your newly created branch on GitHub. + +[[send-pr-ggg]] +=== Sending a PR to GitGitGadget + +In order to have your code tested and formatted for review, you need to start by +opening a Pull Request against `gitgitgadget/git`. Head to +https://github.com/gitgitgadget/git and open a PR either with the "New pull +request" button or the convenient "Compare & pull request" button that may +appear with the name of your newly pushed branch. + +Review the PR's title and description, as it's used by GitGitGadget as the cover +letter for your change. When you're happy, submit your pull request. + +[[run-ci-ggg]] +=== Running CI and Getting Ready to Send + +If it's your first time using GitGitGadget (which is likely, as you're using +this tutorial) then someone will need to give you permission to use the tool. +As mentioned in the GitGitGadget documentation, you just need someone who +already uses it to comment on your PR with `/allow <username>`. GitGitGadget +will automatically run your PRs through the CI even without the permission given +but you will not be able to `/submit` your changes until someone allows you to +use the tool. + +NOTE: You can typically find someone who can `/allow` you on GitGitGadget by +either examining recent pull requests where someone has been granted `/allow` +(https://github.com/gitgitgadget/git/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+%22%2Fallow%22[Search: +is:pr is:open "/allow"]), in which case both the author and the person who +granted the `/allow` can now `/allow` you, or by inquiring on the +https://web.libera.chat/#git-devel[#git-devel] IRC channel on Libera Chat +linking your pull request and asking for someone to `/allow` you. + +If the CI fails, you can update your changes with `git rebase -i` and push your +branch again: + +---- +$ git push -f remotename psuh +---- + +In fact, you should continue to make changes this way up until the point when +your patch is accepted into `next`. + +//// +TODO https://github.com/gitgitgadget/gitgitgadget/issues/83 +It'd be nice to be able to verify that the patch looks good before sending it +to everyone on Git mailing list. +[[check-work-ggg]] +=== Check Your Work +//// + +[[send-mail-ggg]] +=== Sending Your Patches + +Now that your CI is passing and someone has granted you permission to use +GitGitGadget with the `/allow` command, sending out for review is as simple as +commenting on your PR with `/submit`. + +[[responding-ggg]] +=== Updating With Comments + +Skip ahead to <<reviewing,Responding to Reviews>> for information on how to +reply to review comments you will receive on the mailing list. + +Once you have your branch again in the shape you want following all review +comments, you can submit again: + +---- +$ git push -f remotename psuh +---- + +Next, go look at your pull request against GitGitGadget; you should see the CI +has been kicked off again. Now while the CI is running is a good time for you +to modify your description at the top of the pull request thread; it will be +used again as the cover letter. You should use this space to describe what +has changed since your previous version, so that your reviewers have some idea +of what they're looking at. When the CI is done running, you can comment once +more with `/submit` - GitGitGadget will automatically add a v2 mark to your +changes. + +[[howto-git-send-email]] +== Sending Patches with `git send-email` + +If you don't want to use GitGitGadget, you can also use Git itself to mail your +patches. Some benefits of using Git this way include finer grained control of +subject line (for example, being able to use the tag [RFC PATCH] in the subject) +and being able to send a ``dry run'' mail to yourself to ensure it all looks +good before going out to the list. + +[[setup-git-send-email]] +=== Prerequisite: Setting Up `git send-email` + +Configuration for `send-email` can vary based on your operating system and email +provider, and so will not be covered in this tutorial, beyond stating that in +many distributions of Linux, `git-send-email` is not packaged alongside the +typical `git` install. You may need to install this additional package; there +are a number of resources online to help you do so. You will also need to +determine the right way to configure it to use your SMTP server; again, as this +configuration can change significantly based on your system and email setup, it +is out of scope for the context of this tutorial. + +[[format-patch]] +=== Preparing Initial Patchset + +Sending emails with Git is a two-part process; before you can prepare the emails +themselves, you'll need to prepare the patches. Luckily, this is pretty simple: + +---- +$ git format-patch --cover-letter -o psuh/ master..psuh +---- + +The `--cover-letter` parameter tells `format-patch` to create a cover letter +template for you. You will need to fill in the template before you're ready +to send - but for now, the template will be next to your other patches. + +The `-o psuh/` parameter tells `format-patch` to place the patch files into a +directory. This is useful because `git send-email` can take a directory and +send out all the patches from there. + +`master..psuh` tells `format-patch` to generate patches for the difference +between `master` and `psuh`. It will make one patch file per commit. After you +run, you can go have a look at each of the patches with your favorite text +editor and make sure everything looks alright; however, it's not recommended to +make code fixups via the patch file. It's a better idea to make the change the +normal way using `git rebase -i` or by adding a new commit than by modifying a +patch. + +NOTE: Optionally, you can also use the `--rfc` flag to prefix your patch subject +with ``[RFC PATCH]'' instead of ``[PATCH]''. RFC stands for ``request for +comments'' and indicates that while your code isn't quite ready for submission, +you'd like to begin the code review process. This can also be used when your +patch is a proposal, but you aren't sure whether the community wants to solve +the problem with that approach or not - to conduct a sort of design review. You +may also see on the list patches marked ``WIP'' - this means they are incomplete +but want reviewers to look at what they have so far. You can add this flag with +`--subject-prefix=WIP`. + +Check and make sure that your patches and cover letter template exist in the +directory you specified - you're nearly ready to send out your review! + +[[cover-letter]] +=== Preparing Email + +In addition to an email per patch, the Git community also expects your patches +to come with a cover letter, typically with a subject line [PATCH 0/x] (where +x is the number of patches you're sending). Since you invoked `format-patch` +with `--cover-letter`, you've already got a template ready. Open it up in your +favorite editor. + +You should see a number of headers present already. Check that your `From:` +header is correct. Then modify your `Subject:` to something which succinctly +covers the purpose of your entire topic branch, for example: + +---- +Subject: [PATCH 0/7] adding the 'psuh' command +---- + +Make sure you retain the ``[PATCH 0/X]'' part; that's what indicates to the Git +community that this email is the beginning of a review, and many reviewers +filter their email for this type of flag. + +You'll need to add some extra parameters when you invoke `git send-email` to add +the cover letter. + +Next you'll have to fill out the body of your cover letter. This is an important +component of change submission as it explains to the community from a high level +what you're trying to do, and why, in a way that's more apparent than just +looking at your diff. Be sure to explain anything your diff doesn't make clear +on its own. + +Here's an example body for `psuh`: + +---- +Our internal metrics indicate widespread interest in the command +git-psuh - that is, many users are trying to use it, but finding it is +unavailable, using some unknown workaround instead. + +The following handful of patches add the psuh command and implement some +handy features on top of it. + +This patchset is part of the MyFirstContribution tutorial and should not +be merged. +---- + +The template created by `git format-patch --cover-letter` includes a diffstat. +This gives reviewers a summary of what they're in for when reviewing your topic. +The one generated for `psuh` from the sample implementation looks like this: + +---- + Documentation/git-psuh.txt | 40 +++++++++++++++++++++ + Makefile | 1 + + builtin.h | 1 + + builtin/psuh.c | 73 ++++++++++++++++++++++++++++++++++++++ + git.c | 1 + + t/t9999-psuh-tutorial.sh | 12 +++++++ + 6 files changed, 128 insertions(+) + create mode 100644 Documentation/git-psuh.txt + create mode 100644 builtin/psuh.c + create mode 100755 t/t9999-psuh-tutorial.sh +---- + +Finally, the letter will include the version of Git used to generate the +patches. You can leave that string alone. + +[[sending-git-send-email]] +=== Sending Email + +At this point you should have a directory `psuh/` which is filled with your +patches and a cover letter. Time to mail it out! You can send it like this: + +---- +$ git send-email --to=target@example.com psuh/*.patch +---- + +NOTE: Check `git help send-email` for some other options which you may find +valuable, such as changing the Reply-to address or adding more CC and BCC lines. + +NOTE: When you are sending a real patch, it will go to git@vger.kernel.org - but +please don't send your patchset from the tutorial to the real mailing list! For +now, you can send it to yourself, to make sure you understand how it will look. + +After you run the command above, you will be presented with an interactive +prompt for each patch that's about to go out. This gives you one last chance to +edit or quit sending something (but again, don't edit code this way). Once you +press `y` or `a` at these prompts your emails will be sent! Congratulations! + +Awesome, now the community will drop everything and review your changes. (Just +kidding - be patient!) + +[[v2-git-send-email]] +=== Sending v2 + +Skip ahead to <<reviewing,Responding to Reviews>> for information on how to +handle comments from reviewers. Continue this section when your topic branch is +shaped the way you want it to look for your patchset v2. + +When you're ready with the next iteration of your patch, the process is fairly +similar. + +First, generate your v2 patches again: + +---- +$ git format-patch -v2 --cover-letter -o psuh/ master..psuh +---- + +This will add your v2 patches, all named like `v2-000n-my-commit-subject.patch`, +to the `psuh/` directory. You may notice that they are sitting alongside the v1 +patches; that's fine, but be careful when you are ready to send them. + +Edit your cover letter again. Now is a good time to mention what's different +between your last version and now, if it's something significant. You do not +need the exact same body in your second cover letter; focus on explaining to +reviewers the changes you've made that may not be as visible. + +You will also need to go and find the Message-Id of your previous cover letter. +You can either note it when you send the first series, from the output of `git +send-email`, or you can look it up on the +https://lore.kernel.org/git[mailing list]. Find your cover letter in the +archives, click on it, then click "permalink" or "raw" to reveal the Message-Id +header. It should match: + +---- +Message-Id: <foo.12345.author@example.com> +---- + +Your Message-Id is `<foo.12345.author@example.com>`. This example will be used +below as well; make sure to replace it with the correct Message-Id for your +**previous cover letter** - that is, if you're sending v2, use the Message-Id +from v1; if you're sending v3, use the Message-Id from v2. + +While you're looking at the email, you should also note who is CC'd, as it's +common practice in the mailing list to keep all CCs on a thread. You can add +these CC lines directly to your cover letter with a line like so in the header +(before the Subject line): + +---- +CC: author@example.com, Othe R <other@example.com> +---- + +Now send the emails again, paying close attention to which messages you pass in +to the command: + +---- +$ git send-email --to=target@example.com + --in-reply-to="<foo.12345.author@example.com>" + psuh/v2* +---- + +[[single-patch]] +=== Bonus Chapter: One-Patch Changes + +In some cases, your very small change may consist of only one patch. When that +happens, you only need to send one email. Your commit message should already be +meaningful and explain at a high level the purpose (what is happening and why) +of your patch, but if you need to supply even more context, you can do so below +the `---` in your patch. Take the example below, which was generated with `git +format-patch` on a single commit, and then edited to add the content between +the `---` and the diffstat. + +---- +From 1345bbb3f7ac74abde040c12e737204689a72723 Mon Sep 17 00:00:00 2001 +From: A U Thor <author@example.com> +Date: Thu, 18 Apr 2019 15:11:02 -0700 +Subject: [PATCH] README: change the grammar + +I think it looks better this way. This part of the commit message will +end up in the commit-log. + +Signed-off-by: A U Thor <author@example.com> +--- +Let's have a wild discussion about grammar on the mailing list. This +part of my email will never end up in the commit log. Here is where I +can add additional context to the mailing list about my intent, outside +of the context of the commit log. This section was added after `git +format-patch` was run, by editing the patch file in a text editor. + + README.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/README.md b/README.md +index 88f126184c..38da593a60 100644 +--- a/README.md ++++ b/README.md +@@ -3,7 +3,7 @@ + Git - fast, scalable, distributed revision control system + ========================================================= + +-Git is a fast, scalable, distributed revision control system with an ++Git is a fast, scalable, and distributed revision control system with an + unusually rich command set that provides both high-level operations + and full access to internals. + +-- +2.21.0.392.gf8f6787159e-goog +---- + +[[now-what]] +== My Patch Got Emailed - Now What? + +[[reviewing]] +=== Responding to Reviews + +After a few days, you will hopefully receive a reply to your patchset with some +comments. Woohoo! Now you can get back to work. + +It's good manners to reply to each comment, notifying the reviewer that you have +made the change suggested, feel the original is better, or that the comment +inspired you to do something a new way which is superior to both the original +and the suggested change. This way reviewers don't need to inspect your v2 to +figure out whether you implemented their comment or not. + +Reviewers may ask you about what you wrote in the patchset, either in +the proposed commit log message or in the changes themselves. You +should answer these questions in your response messages, but often the +reason why reviewers asked these questions to understand what you meant +to write is because your patchset needed clarification to be understood. + +Do not be satisfied by just answering their questions in your response +and hear them say that they now understand what you wanted to say. +Update your patches to clarify the points reviewers had trouble with, +and prepare your v2; the words you used to explain your v1 to answer +reviewers' questions may be useful thing to use. Your goal is to make +your v2 clear enough so that it becomes unnecessary for you to give the +same explanation to the next person who reads it. + +If you are going to push back on a comment, be polite and explain why you feel +your original is better; be prepared that the reviewer may still disagree with +you, and the rest of the community may weigh in on one side or the other. As +with all code reviews, it's important to keep an open mind to doing something a +different way than you originally planned; other reviewers have a different +perspective on the project than you do, and may be thinking of a valid side +effect which had not occurred to you. It is always okay to ask for clarification +if you aren't sure why a change was suggested, or what the reviewer is asking +you to do. + +Make sure your email client has a plaintext email mode and it is turned on; the +Git list rejects HTML email. Please also follow the mailing list etiquette +outlined in the +https://kernel.googlesource.com/pub/scm/git/git/+/todo/MaintNotes[Maintainer's +Note], which are similar to etiquette rules in most open source communities +surrounding bottom-posting and inline replies. + +When you're making changes to your code, it is cleanest - that is, the resulting +commits are easiest to look at - if you use `git rebase -i` (interactive +rebase). Take a look at this +https://www.oreilly.com/library/view/git-pocket-guide/9781449327507/ch10.html[overview] +from O'Reilly. The general idea is to modify each commit which requires changes; +this way, instead of having a patch A with a mistake, a patch B which was fine +and required no upstream reviews in v1, and a patch C which fixes patch A for +v2, you can just ship a v2 with a correct patch A and correct patch B. This is +changing history, but since it's local history which you haven't shared with +anyone, that is okay for now! (Later, it may not make sense to do this; take a +look at the section below this one for some context.) + +[[after-approval]] +=== After Review Approval + +The Git project has four integration branches: `seen`, `next`, `master`, and +`maint`. Your change will be placed into `seen` fairly early on by the maintainer +while it is still in the review process; from there, when it is ready for wider +testing, it will be merged into `next`. Plenty of early testers use `next` and +may report issues. Eventually, changes in `next` will make it to `master`, +which is typically considered stable. Finally, when a new release is cut, +`maint` is used to base bugfixes onto. As mentioned at the beginning of this +document, you can read `Documents/SubmittingPatches` for some more info about +the use of the various integration branches. + +Back to now: your code has been lauded by the upstream reviewers. It is perfect. +It is ready to be accepted. You don't need to do anything else; the maintainer +will merge your topic branch to `next` and life is good. + +However, if you discover it isn't so perfect after this point, you may need to +take some special steps depending on where you are in the process. + +If the maintainer has announced in the "What's cooking in git.git" email that +your topic is marked for `next` - that is, that they plan to merge it to `next` +but have not yet done so - you should send an email asking the maintainer to +wait a little longer: "I've sent v4 of my series and you marked it for `next`, +but I need to change this and that - please wait for v5 before you merge it." + +If the topic has already been merged to `next`, rather than modifying your +patches with `git rebase -i`, you should make further changes incrementally - +that is, with another commit, based on top of the maintainer's topic branch as +detailed in https://github.com/gitster/git. Your work is still in the same topic +but is now incremental, rather than a wholesale rewrite of the topic branch. + +The topic branches in the maintainer's GitHub are mirrored in GitGitGadget, so +if you're sending your reviews out that way, you should be sure to open your PR +against the appropriate GitGitGadget/Git branch. + +If you're using `git send-email`, you can use it the same way as before, but you +should generate your diffs from `<topic>..<mybranch>` and base your work on +`<topic>` instead of `master`. diff --git a/Documentation/MyFirstObjectWalk.txt b/Documentation/MyFirstObjectWalk.txt new file mode 100644 index 0000000000..2d10eea7a9 --- /dev/null +++ b/Documentation/MyFirstObjectWalk.txt @@ -0,0 +1,870 @@ += My First Object Walk + +== What's an Object Walk? + +The object walk is a key concept in Git - this is the process that underpins +operations like object transfer and fsck. Beginning from a given commit, the +list of objects is found by walking parent relationships between commits (commit +X based on commit W) and containment relationships between objects (tree Y is +contained within commit X, and blob Z is located within tree Y, giving our +working tree for commit X something like `y/z.txt`). + +A related concept is the revision walk, which is focused on commit objects and +their parent relationships and does not delve into other object types. The +revision walk is used for operations like `git log`. + +=== Related Reading + +- `Documentation/user-manual.txt` under "Hacking Git" contains some coverage of + the revision walker in its various incarnations. +- `revision.h` +- https://eagain.net/articles/git-for-computer-scientists/[Git for Computer Scientists] + gives a good overview of the types of objects in Git and what your object + walk is really describing. + +== Setting Up + +Create a new branch from `master`. + +---- +git checkout -b revwalk origin/master +---- + +We'll put our fiddling into a new command. For fun, let's name it `git walken`. +Open up a new file `builtin/walken.c` and set up the command handler: + +---- +/* + * "git walken" + * + * Part of the "My First Object Walk" tutorial. + */ + +#include "builtin.h" + +int cmd_walken(int argc, const char **argv, const char *prefix) +{ + trace_printf(_("cmd_walken incoming...\n")); + return 0; +} +---- + +NOTE: `trace_printf()` differs from `printf()` in that it can be turned on or +off at runtime. For the purposes of this tutorial, we will write `walken` as +though it is intended for use as a "plumbing" command: that is, a command which +is used primarily in scripts, rather than interactively by humans (a "porcelain" +command). So we will send our debug output to `trace_printf()` instead. When +running, enable trace output by setting the environment variable `GIT_TRACE`. + +Add usage text and `-h` handling, like all subcommands should consistently do +(our test suite will notice and complain if you fail to do so). + +---- +int cmd_walken(int argc, const char **argv, const char *prefix) +{ + const char * const walken_usage[] = { + N_("git walken"), + NULL, + } + struct option options[] = { + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, walken_usage, 0); + + ... +} +---- + +Also add the relevant line in `builtin.h` near `cmd_whatchanged()`: + +---- +int cmd_walken(int argc, const char **argv, const char *prefix); +---- + +Include the command in `git.c` in `commands[]` near the entry for `whatchanged`, +maintaining alphabetical ordering: + +---- +{ "walken", cmd_walken, RUN_SETUP }, +---- + +Add it to the `Makefile` near the line for `builtin/worktree.o`: + +---- +BUILTIN_OBJS += builtin/walken.o +---- + +Build and test out your command, without forgetting to ensure the `DEVELOPER` +flag is set, and with `GIT_TRACE` enabled so the debug output can be seen: + +---- +$ echo DEVELOPER=1 >>config.mak +$ make +$ GIT_TRACE=1 ./bin-wrappers/git walken +---- + +NOTE: For a more exhaustive overview of the new command process, take a look at +`Documentation/MyFirstContribution.txt`. + +NOTE: A reference implementation can be found at +https://github.com/nasamuffin/git/tree/revwalk. + +=== `struct rev_cmdline_info` + +The definition of `struct rev_cmdline_info` can be found in `revision.h`. + +This struct is contained within the `rev_info` struct and is used to reflect +parameters provided by the user over the CLI. + +`nr` represents the number of `rev_cmdline_entry` present in the array. + +`alloc` is used by the `ALLOC_GROW` macro. Check `cache.h` - this variable is +used to track the allocated size of the list. + +Per entry, we find: + +`item` is the object provided upon which to base the object walk. Items in Git +can be blobs, trees, commits, or tags. (See `Documentation/gittutorial-2.txt`.) + +`name` is the object ID (OID) of the object - a hex string you may be familiar +with from using Git to organize your source in the past. Check the tutorial +mentioned above towards the top for a discussion of where the OID can come +from. + +`whence` indicates some information about what to do with the parents of the +specified object. We'll explore this flag more later on; take a look at +`Documentation/revisions.txt` to get an idea of what could set the `whence` +value. + +`flags` are used to hint the beginning of the revision walk and are the first +block under the `#include`s in `revision.h`. The most likely ones to be set in +the `rev_cmdline_info` are `UNINTERESTING` and `BOTTOM`, but these same flags +can be used during the walk, as well. + +=== `struct rev_info` + +This one is quite a bit longer, and many fields are only used during the walk +by `revision.c` - not configuration options. Most of the configurable flags in +`struct rev_info` have a mirror in `Documentation/rev-list-options.txt`. It's a +good idea to take some time and read through that document. + +== Basic Commit Walk + +First, let's see if we can replicate the output of `git log --oneline`. We'll +refer back to the implementation frequently to discover norms when performing +an object walk of our own. + +To do so, we'll first find all the commits, in order, which preceded the current +commit. We'll extract the name and subject of the commit from each. + +Ideally, we will also be able to find out which ones are currently at the tip of +various branches. + +=== Setting Up + +Preparing for your object walk has some distinct stages. + +1. Perform default setup for this mode, and others which may be invoked. +2. Check configuration files for relevant settings. +3. Set up the `rev_info` struct. +4. Tweak the initialized `rev_info` to suit the current walk. +5. Prepare the `rev_info` for the walk. +6. Iterate over the objects, processing each one. + +==== Default Setups + +Before examining configuration files which may modify command behavior, set up +default state for switches or options your command may have. If your command +utilizes other Git components, ask them to set up their default states as well. +For instance, `git log` takes advantage of `grep` and `diff` functionality, so +its `init_log_defaults()` sets its own state (`decoration_style`) and asks +`grep` and `diff` to initialize themselves by calling each of their +initialization functions. + +==== Configuring From `.gitconfig` + +Next, we should have a look at any relevant configuration settings (i.e., +settings readable and settable from `git config`). This is done by providing a +callback to `git_config()`; within that callback, you can also invoke methods +from other components you may need that need to intercept these options. Your +callback will be invoked once per each configuration value which Git knows about +(global, local, worktree, etc.). + +Similarly to the default values, we don't have anything to do here yet +ourselves; however, we should call `git_default_config()` if we aren't calling +any other existing config callbacks. + +Add a new function to `builtin/walken.c`: + +---- +static int git_walken_config(const char *var, const char *value, void *cb) +{ + /* + * For now, we don't have any custom configuration, so fall back to + * the default config. + */ + return git_default_config(var, value, cb); +} +---- + +Make sure to invoke `git_config()` with it in your `cmd_walken()`: + +---- +int cmd_walken(int argc, const char **argv, const char *prefix) +{ + ... + + git_config(git_walken_config, NULL); + + ... +} +---- + +==== Setting Up `rev_info` + +Now that we've gathered external configuration and options, it's time to +initialize the `rev_info` object which we will use to perform the walk. This is +typically done by calling `repo_init_revisions()` with the repository you intend +to target, as well as the `prefix` argument of `cmd_walken` and your `rev_info` +struct. + +Add the `struct rev_info` and the `repo_init_revisions()` call: +---- +int cmd_walken(int argc, const char **argv, const char *prefix) +{ + /* This can go wherever you like in your declarations.*/ + struct rev_info rev; + ... + + /* This should go after the git_config() call. */ + repo_init_revisions(the_repository, &rev, prefix); + + ... +} +---- + +==== Tweaking `rev_info` For the Walk + +We're getting close, but we're still not quite ready to go. Now that `rev` is +initialized, we can modify it to fit our needs. This is usually done within a +helper for clarity, so let's add one: + +---- +static void final_rev_info_setup(struct rev_info *rev) +{ + /* + * We want to mimic the appearance of `git log --oneline`, so let's + * force oneline format. + */ + get_commit_format("oneline", rev); + + /* Start our object walk at HEAD. */ + add_head_to_pending(rev); +} +---- + +[NOTE] +==== +Instead of using the shorthand `add_head_to_pending()`, you could do +something like this: +---- + struct setup_revision_opt opt; + + memset(&opt, 0, sizeof(opt)); + opt.def = "HEAD"; + opt.revarg_opt = REVARG_COMMITTISH; + setup_revisions(argc, argv, rev, &opt); +---- +Using a `setup_revision_opt` gives you finer control over your walk's starting +point. +==== + +Then let's invoke `final_rev_info_setup()` after the call to +`repo_init_revisions()`: + +---- +int cmd_walken(int argc, const char **argv, const char *prefix) +{ + ... + + final_rev_info_setup(&rev); + + ... +} +---- + +Later, we may wish to add more arguments to `final_rev_info_setup()`. But for +now, this is all we need. + +==== Preparing `rev_info` For the Walk + +Now that `rev` is all initialized and configured, we've got one more setup step +before we get rolling. We can do this in a helper, which will both prepare the +`rev_info` for the walk, and perform the walk itself. Let's start the helper +with the call to `prepare_revision_walk()`, which can return an error without +dying on its own: + +---- +static void walken_commit_walk(struct rev_info *rev) +{ + if (prepare_revision_walk(rev)) + die(_("revision walk setup failed")); +} +---- + +NOTE: `die()` prints to `stderr` and exits the program. Since it will print to +`stderr` it's likely to be seen by a human, so we will localize it. + +==== Performing the Walk! + +Finally! We are ready to begin the walk itself. Now we can see that `rev_info` +can also be used as an iterator; we move to the next item in the walk by using +`get_revision()` repeatedly. Add the listed variable declarations at the top and +the walk loop below the `prepare_revision_walk()` call within your +`walken_commit_walk()`: + +---- +static void walken_commit_walk(struct rev_info *rev) +{ + struct commit *commit; + struct strbuf prettybuf = STRBUF_INIT; + + ... + + while ((commit = get_revision(rev))) { + strbuf_reset(&prettybuf); + pp_commit_easy(CMIT_FMT_ONELINE, commit, &prettybuf); + puts(prettybuf.buf); + } + strbuf_release(&prettybuf); +} +---- + +NOTE: `puts()` prints a `char*` to `stdout`. Since this is the part of the +command we expect to be machine-parsed, we're sending it directly to stdout. + +Give it a shot. + +---- +$ make +$ ./bin-wrappers/git walken +---- + +You should see all of the subject lines of all the commits in +your tree's history, in order, ending with the initial commit, "Initial revision +of "git", the information manager from hell". Congratulations! You've written +your first revision walk. You can play with printing some additional fields +from each commit if you're curious; have a look at the functions available in +`commit.h`. + +=== Adding a Filter + +Next, let's try to filter the commits we see based on their author. This is +equivalent to running `git log --author=<pattern>`. We can add a filter by +modifying `rev_info.grep_filter`, which is a `struct grep_opt`. + +First some setup. Add `grep_config()` to `git_walken_config()`: + +---- +static int git_walken_config(const char *var, const char *value, void *cb) +{ + grep_config(var, value, cb); + return git_default_config(var, value, cb); +} +---- + +Next, we can modify the `grep_filter`. This is done with convenience functions +found in `grep.h`. For fun, we're filtering to only commits from folks using a +`gmail.com` email address - a not-very-precise guess at who may be working on +Git as a hobby. Since we're checking the author, which is a specific line in the +header, we'll use the `append_header_grep_pattern()` helper. We can use +the `enum grep_header_field` to indicate which part of the commit header we want +to search. + +In `final_rev_info_setup()`, add your filter line: + +---- +static void final_rev_info_setup(int argc, const char **argv, + const char *prefix, struct rev_info *rev) +{ + ... + + append_header_grep_pattern(&rev->grep_filter, GREP_HEADER_AUTHOR, + "gmail"); + compile_grep_patterns(&rev->grep_filter); + + ... +} +---- + +`append_header_grep_pattern()` adds your new "gmail" pattern to `rev_info`, but +it won't work unless we compile it with `compile_grep_patterns()`. + +NOTE: If you are using `setup_revisions()` (for example, if you are passing a +`setup_revision_opt` instead of using `add_head_to_pending()`), you don't need +to call `compile_grep_patterns()` because `setup_revisions()` calls it for you. + +NOTE: We could add the same filter via the `append_grep_pattern()` helper if we +wanted to, but `append_header_grep_pattern()` adds the `enum grep_context` and +`enum grep_pat_token` for us. + +=== Changing the Order + +There are a few ways that we can change the order of the commits during a +revision walk. Firstly, we can use the `enum rev_sort_order` to choose from some +typical orderings. + +`topo_order` is the same as `git log --topo-order`: we avoid showing a parent +before all of its children have been shown, and we avoid mixing commits which +are in different lines of history. (`git help log`'s section on `--topo-order` +has a very nice diagram to illustrate this.) + +Let's see what happens when we run with `REV_SORT_BY_COMMIT_DATE` as opposed to +`REV_SORT_BY_AUTHOR_DATE`. Add the following: + +---- +static void final_rev_info_setup(int argc, const char **argv, + const char *prefix, struct rev_info *rev) +{ + ... + + rev->topo_order = 1; + rev->sort_order = REV_SORT_BY_COMMIT_DATE; + + ... +} +---- + +Let's output this into a file so we can easily diff it with the walk sorted by +author date. + +---- +$ make +$ ./bin-wrappers/git walken > commit-date.txt +---- + +Then, let's sort by author date and run it again. + +---- +static void final_rev_info_setup(int argc, const char **argv, + const char *prefix, struct rev_info *rev) +{ + ... + + rev->topo_order = 1; + rev->sort_order = REV_SORT_BY_AUTHOR_DATE; + + ... +} +---- + +---- +$ make +$ ./bin-wrappers/git walken > author-date.txt +---- + +Finally, compare the two. This is a little less helpful without object names or +dates, but hopefully we get the idea. + +---- +$ diff -u commit-date.txt author-date.txt +---- + +This display indicates that commits can be reordered after they're written, for +example with `git rebase`. + +Let's try one more reordering of commits. `rev_info` exposes a `reverse` flag. +Set that flag somewhere inside of `final_rev_info_setup()`: + +---- +static void final_rev_info_setup(int argc, const char **argv, const char *prefix, + struct rev_info *rev) +{ + ... + + rev->reverse = 1; + + ... +} +---- + +Run your walk again and note the difference in order. (If you remove the grep +pattern, you should see the last commit this call gives you as your current +HEAD.) + +== Basic Object Walk + +So far we've been walking only commits. But Git has more types of objects than +that! Let's see if we can walk _all_ objects, and find out some information +about each one. + +We can base our work on an example. `git pack-objects` prepares all kinds of +objects for packing into a bitmap or packfile. The work we are interested in +resides in `builtins/pack-objects.c:get_object_list()`; examination of that +function shows that the all-object walk is being performed by +`traverse_commit_list()` or `traverse_commit_list_filtered()`. Those two +functions reside in `list-objects.c`; examining the source shows that, despite +the name, these functions traverse all kinds of objects. Let's have a look at +the arguments to `traverse_commit_list_filtered()`, which are a superset of the +arguments to the unfiltered version. + +- `struct list_objects_filter_options *filter_options`: This is a struct which + stores a filter-spec as outlined in `Documentation/rev-list-options.txt`. +- `struct rev_info *revs`: This is the `rev_info` used for the walk. +- `show_commit_fn show_commit`: A callback which will be used to handle each + individual commit object. +- `show_object_fn show_object`: A callback which will be used to handle each + non-commit object (so each blob, tree, or tag). +- `void *show_data`: A context buffer which is passed in turn to `show_commit` + and `show_object`. +- `struct oidset *omitted`: A linked-list of object IDs which the provided + filter caused to be omitted. + +It looks like this `traverse_commit_list_filtered()` uses callbacks we provide +instead of needing us to call it repeatedly ourselves. Cool! Let's add the +callbacks first. + +For the sake of this tutorial, we'll simply keep track of how many of each kind +of object we find. At file scope in `builtin/walken.c` add the following +tracking variables: + +---- +static int commit_count; +static int tag_count; +static int blob_count; +static int tree_count; +---- + +Commits are handled by a different callback than other objects; let's do that +one first: + +---- +static void walken_show_commit(struct commit *cmt, void *buf) +{ + commit_count++; +} +---- + +The `cmt` argument is fairly self-explanatory. But it's worth mentioning that +the `buf` argument is actually the context buffer that we can provide to the +traversal calls - `show_data`, which we mentioned a moment ago. + +Since we have the `struct commit` object, we can look at all the same parts that +we looked at in our earlier commit-only walk. For the sake of this tutorial, +though, we'll just increment the commit counter and move on. + +The callback for non-commits is a little different, as we'll need to check +which kind of object we're dealing with: + +---- +static void walken_show_object(struct object *obj, const char *str, void *buf) +{ + switch (obj->type) { + case OBJ_TREE: + tree_count++; + break; + case OBJ_BLOB: + blob_count++; + break; + case OBJ_TAG: + tag_count++; + break; + case OBJ_COMMIT: + BUG("unexpected commit object in walken_show_object\n"); + default: + BUG("unexpected object type %s in walken_show_object\n", + type_name(obj->type)); + } +} +---- + +Again, `obj` is fairly self-explanatory, and we can guess that `buf` is the same +context pointer that `walken_show_commit()` receives: the `show_data` argument +to `traverse_commit_list()` and `traverse_commit_list_filtered()`. Finally, +`str` contains the name of the object, which ends up being something like +`foo.txt` (blob), `bar/baz` (tree), or `v1.2.3` (tag). + +To help assure us that we aren't double-counting commits, we'll include some +complaining if a commit object is routed through our non-commit callback; we'll +also complain if we see an invalid object type. Since those two cases should be +unreachable, and would only change in the event of a semantic change to the Git +codebase, we complain by using `BUG()` - which is a signal to a developer that +the change they made caused unintended consequences, and the rest of the +codebase needs to be updated to understand that change. `BUG()` is not intended +to be seen by the public, so it is not localized. + +Our main object walk implementation is substantially different from our commit +walk implementation, so let's make a new function to perform the object walk. We +can perform setup which is applicable to all objects here, too, to keep separate +from setup which is applicable to commit-only walks. + +We'll start by enabling all types of objects in the `struct rev_info`. We'll +also turn on `tree_blobs_in_commit_order`, which means that we will walk a +commit's tree and everything it points to immediately after we find each commit, +as opposed to waiting for the end and walking through all trees after the commit +history has been discovered. With the appropriate settings configured, we are +ready to call `prepare_revision_walk()`. + +---- +static void walken_object_walk(struct rev_info *rev) +{ + rev->tree_objects = 1; + rev->blob_objects = 1; + rev->tag_objects = 1; + rev->tree_blobs_in_commit_order = 1; + + if (prepare_revision_walk(rev)) + die(_("revision walk setup failed")); + + commit_count = 0; + tag_count = 0; + blob_count = 0; + tree_count = 0; +---- + +Let's start by calling just the unfiltered walk and reporting our counts. +Complete your implementation of `walken_object_walk()`: + +---- + traverse_commit_list(rev, walken_show_commit, walken_show_object, NULL); + + printf("commits %d\nblobs %d\ntags %d\ntrees %d\n", commit_count, + blob_count, tag_count, tree_count); +} +---- + +NOTE: This output is intended to be machine-parsed. Therefore, we are not +sending it to `trace_printf()`, and we are not localizing it - we need scripts +to be able to count on the formatting to be exactly the way it is shown here. +If we were intending this output to be read by humans, we would need to localize +it with `_()`. + +Finally, we'll ask `cmd_walken()` to use the object walk instead. Discussing +command line options is out of scope for this tutorial, so we'll just hardcode +a branch we can change at compile time. Where you call `final_rev_info_setup()` +and `walken_commit_walk()`, instead branch like so: + +---- + if (1) { + add_head_to_pending(&rev); + walken_object_walk(&rev); + } else { + final_rev_info_setup(argc, argv, prefix, &rev); + walken_commit_walk(&rev); + } +---- + +NOTE: For simplicity, we've avoided all the filters and sorts we applied in +`final_rev_info_setup()` and simply added `HEAD` to our pending queue. If you +want, you can certainly use the filters we added before by moving +`final_rev_info_setup()` out of the conditional and removing the call to +`add_head_to_pending()`. + +Now we can try to run our command! It should take noticeably longer than the +commit walk, but an examination of the output will give you an idea why. Your +output should look similar to this example, but with different counts: + +---- +Object walk completed. Found 55733 commits, 100274 blobs, 0 tags, and 104210 trees. +---- + +This makes sense. We have more trees than commits because the Git project has +lots of subdirectories which can change, plus at least one tree per commit. We +have no tags because we started on a commit (`HEAD`) and while tags can point to +commits, commits can't point to tags. + +NOTE: You will have different counts when you run this yourself! The number of +objects grows along with the Git project. + +=== Adding a Filter + +There are a handful of filters that we can apply to the object walk laid out in +`Documentation/rev-list-options.txt`. These filters are typically useful for +operations such as creating packfiles or performing a partial clone. They are +defined in `list-objects-filter-options.h`. For the purposes of this tutorial we +will use the "tree:1" filter, which causes the walk to omit all trees and blobs +which are not directly referenced by commits reachable from the commit in +`pending` when the walk begins. (`pending` is the list of objects which need to +be traversed during a walk; you can imagine a breadth-first tree traversal to +help understand. In our case, that means we omit trees and blobs not directly +referenced by `HEAD` or `HEAD`'s history, because we begin the walk with only +`HEAD` in the `pending` list.) + +First, we'll need to `#include "list-objects-filter-options.h`" and set up the +`struct list_objects_filter_options` at the top of the function. + +---- +static void walken_object_walk(struct rev_info *rev) +{ + struct list_objects_filter_options filter_options = {}; + + ... +---- + +For now, we are not going to track the omitted objects, so we'll replace those +parameters with `NULL`. For the sake of simplicity, we'll add a simple +build-time branch to use our filter or not. Replace the line calling +`traverse_commit_list()` with the following, which will remind us which kind of +walk we've just performed: + +---- + if (0) { + /* Unfiltered: */ + trace_printf(_("Unfiltered object walk.\n")); + traverse_commit_list(rev, walken_show_commit, + walken_show_object, NULL); + } else { + trace_printf( + _("Filtered object walk with filterspec 'tree:1'.\n")); + parse_list_objects_filter(&filter_options, "tree:1"); + + traverse_commit_list_filtered(&filter_options, rev, + walken_show_commit, walken_show_object, NULL, NULL); + } +---- + +`struct list_objects_filter_options` is usually built directly from a command +line argument, so the module provides an easy way to build one from a string. +Even though we aren't taking user input right now, we can still build one with +a hardcoded string using `parse_list_objects_filter()`. + +With the filter spec "tree:1", we are expecting to see _only_ the root tree for +each commit; therefore, the tree object count should be less than or equal to +the number of commits. (For an example of why that's true: `git commit --revert` +points to the same tree object as its grandparent.) + +=== Counting Omitted Objects + +We also have the capability to enumerate all objects which were omitted by a +filter, like with `git log --filter=<spec> --filter-print-omitted`. Asking +`traverse_commit_list_filtered()` to populate the `omitted` list means that our +object walk does not perform any better than an unfiltered object walk; all +reachable objects are walked in order to populate the list. + +First, add the `struct oidset` and related items we will use to iterate it: + +---- +static void walken_object_walk( + ... + + struct oidset omitted; + struct oidset_iter oit; + struct object_id *oid = NULL; + int omitted_count = 0; + oidset_init(&omitted, 0); + + ... +---- + +Modify the call to `traverse_commit_list_filtered()` to include your `omitted` +object: + +---- + ... + + traverse_commit_list_filtered(&filter_options, rev, + walken_show_commit, walken_show_object, NULL, &omitted); + + ... +---- + +Then, after your traversal, the `oidset` traversal is pretty straightforward. +Count all the objects within and modify the print statement: + +---- + /* Count the omitted objects. */ + oidset_iter_init(&omitted, &oit); + + while ((oid = oidset_iter_next(&oit))) + omitted_count++; + + printf("commits %d\nblobs %d\ntags %d\ntrees%d\nomitted %d\n", + commit_count, blob_count, tag_count, tree_count, omitted_count); +---- + +By running your walk with and without the filter, you should find that the total +object count in each case is identical. You can also time each invocation of +the `walken` subcommand, with and without `omitted` being passed in, to confirm +to yourself the runtime impact of tracking all omitted objects. + +=== Changing the Order + +Finally, let's demonstrate that you can also reorder walks of all objects, not +just walks of commits. First, we'll make our handlers chattier - modify +`walken_show_commit()` and `walken_show_object()` to print the object as they +go: + +---- +static void walken_show_commit(struct commit *cmt, void *buf) +{ + trace_printf("commit: %s\n", oid_to_hex(&cmt->object.oid)); + commit_count++; +} + +static void walken_show_object(struct object *obj, const char *str, void *buf) +{ + trace_printf("%s: %s\n", type_name(obj->type), oid_to_hex(&obj->oid)); + + ... +} +---- + +NOTE: Since we will be examining this output directly as humans, we'll use +`trace_printf()` here. Additionally, since this change introduces a significant +number of printed lines, using `trace_printf()` will allow us to easily silence +those lines without having to recompile. + +(Leave the counter increment logic in place.) + +With only that change, run again (but save yourself some scrollback): + +---- +$ GIT_TRACE=1 ./bin-wrappers/git walken | head -n 10 +---- + +Take a look at the top commit with `git show` and the object ID you printed; it +should be the same as the output of `git show HEAD`. + +Next, let's change a setting on our `struct rev_info` within +`walken_object_walk()`. Find where you're changing the other settings on `rev`, +such as `rev->tree_objects` and `rev->tree_blobs_in_commit_order`, and add the +`reverse` setting at the bottom: + +---- + ... + + rev->tree_objects = 1; + rev->blob_objects = 1; + rev->tag_objects = 1; + rev->tree_blobs_in_commit_order = 1; + rev->reverse = 1; + + ... +---- + +Now, run again, but this time, let's grab the last handful of objects instead +of the first handful: + +---- +$ make +$ GIT_TRACE=1 ./bin-wrappers git walken | tail -n 10 +---- + +The last commit object given should have the same OID as the one we saw at the +top before, and running `git show <oid>` with that OID should give you again +the same results as `git show HEAD`. Furthermore, if you run and examine the +first ten lines again (with `head` instead of `tail` like we did before applying +the `reverse` setting), you should see that now the first commit printed is the +initial commit, `e83c5163`. + +== Wrapping Up + +Let's review. In this tutorial, we: + +- Built a commit walk from the ground up +- Enabled a grep filter for that commit walk +- Changed the sort order of that filtered commit walk +- Built an object walk (tags, commits, trees, and blobs) from the ground up +- Learned how to add a filter-spec to an object walk +- Changed the display order of the filtered object walk diff --git a/Documentation/RelNotes/1.5.0.txt b/Documentation/RelNotes/1.5.0.txt index daf4bdb0d7..d6d42f3183 100644 --- a/Documentation/RelNotes/1.5.0.txt +++ b/Documentation/RelNotes/1.5.0.txt @@ -251,7 +251,7 @@ Updates in v1.5.0 since v1.4.4 series the repository when that happens. -* Crufts removal +* Cruft removal - We used to say "old commits are retrievable using reflog and 'master@{yesterday}' syntax as long as you haven't run @@ -379,7 +379,7 @@ Updates in v1.5.0 since v1.4.4 series - The value of i18n.commitencoding in the originating repository is recorded in the commit object on the "encoding" header, if it is not UTF-8. git-log and friends notice this, - and reencodes the message to the log output encoding when + and re-encodes the message to the log output encoding when displaying, if they are different. The log output encoding is determined by "git log --encoding=<encoding>", i18n.logoutputencoding configuration, or i18n.commitencoding diff --git a/Documentation/RelNotes/1.6.0.3.txt b/Documentation/RelNotes/1.6.0.3.txt index ae0577836a..ad36c0f0b7 100644 --- a/Documentation/RelNotes/1.6.0.3.txt +++ b/Documentation/RelNotes/1.6.0.3.txt @@ -50,7 +50,7 @@ Fixes since v1.6.0.2 if the working tree is currently dirty. * "git for-each-ref --format=%(subject)" fixed for commits with no - no newline in the message body. + newline in the message body. * "git remote" fixed to protect printf from user input. diff --git a/Documentation/RelNotes/1.6.2.txt b/Documentation/RelNotes/1.6.2.txt index ad060f4f89..980adfb315 100644 --- a/Documentation/RelNotes/1.6.2.txt +++ b/Documentation/RelNotes/1.6.2.txt @@ -11,7 +11,7 @@ push running this release will issue a big warning when the configuration variable is missing. Please refer to: http://git.or.cz/gitwiki/GitFaq#non-bare - http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007 + https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the transition plan. diff --git a/Documentation/RelNotes/1.6.3.txt b/Documentation/RelNotes/1.6.3.txt index 418c685cf8..4bcff945e0 100644 --- a/Documentation/RelNotes/1.6.3.txt +++ b/Documentation/RelNotes/1.6.3.txt @@ -11,7 +11,7 @@ push running this release will issue a big warning when the configuration variable is missing. Please refer to: http://git.or.cz/gitwiki/GitFaq#non-bare - http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007 + https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the transition plan. diff --git a/Documentation/RelNotes/1.6.4.txt b/Documentation/RelNotes/1.6.4.txt index 7a904419f7..a2a34b43a7 100644 --- a/Documentation/RelNotes/1.6.4.txt +++ b/Documentation/RelNotes/1.6.4.txt @@ -11,7 +11,7 @@ push running this release will issue a big warning when the configuration variable is missing. Please refer to: http://git.or.cz/gitwiki/GitFaq#non-bare - http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007 + https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the transition plan. diff --git a/Documentation/RelNotes/1.6.5.4.txt b/Documentation/RelNotes/1.6.5.4.txt index d3a2a3e712..344333de66 100644 --- a/Documentation/RelNotes/1.6.5.4.txt +++ b/Documentation/RelNotes/1.6.5.4.txt @@ -10,7 +10,7 @@ Fixes since v1.6.5.3 * "git prune-packed" gave progress output even when its standard error is not connected to a terminal; this caused cron jobs that run it to - produce crufts. + produce cruft. * "git pack-objects --all-progress" is an option to ask progress output from write-object phase _if_ progress output were to be produced, and diff --git a/Documentation/RelNotes/1.6.5.txt b/Documentation/RelNotes/1.6.5.txt index ee141c19ad..6c7f7da7eb 100644 --- a/Documentation/RelNotes/1.6.5.txt +++ b/Documentation/RelNotes/1.6.5.txt @@ -22,7 +22,7 @@ push running this release will issue a big warning when the configuration variable is missing. Please refer to: http://git.or.cz/gitwiki/GitFaq#non-bare - http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007 + https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the transition plan. diff --git a/Documentation/RelNotes/1.6.6.txt b/Documentation/RelNotes/1.6.6.txt index c50b59c495..3ed1e01433 100644 --- a/Documentation/RelNotes/1.6.6.txt +++ b/Documentation/RelNotes/1.6.6.txt @@ -64,7 +64,7 @@ users will fare this time. Please refer to: http://git.or.cz/gitwiki/GitFaq#non-bare - http://thread.gmane.org/gmane.comp.version-control.git/107758/focus=108007 + https://lore.kernel.org/git/7vbptlsuyv.fsf@gitster.siamese.dyndns.org/ for more details on the reason why this change is needed and the transition process that already took place so far. diff --git a/Documentation/RelNotes/1.7.0.2.txt b/Documentation/RelNotes/1.7.0.2.txt index fcb46ca6a4..73ed2b5278 100644 --- a/Documentation/RelNotes/1.7.0.2.txt +++ b/Documentation/RelNotes/1.7.0.2.txt @@ -34,7 +34,7 @@ Fixes since v1.7.0.1 * "git status" in 1.7.0 lacked the optimization we used to have in 1.6.X series to speed up scanning of large working tree. - * "gitweb" did not diagnose parsing errors properly while reading tis configuration + * "gitweb" did not diagnose parsing errors properly while reading its configuration file. And other minor fixes and documentation updates. diff --git a/Documentation/RelNotes/1.7.10.4.txt b/Documentation/RelNotes/1.7.10.4.txt index 326670df6e..57597f2bf3 100644 --- a/Documentation/RelNotes/1.7.10.4.txt +++ b/Documentation/RelNotes/1.7.10.4.txt @@ -7,7 +7,7 @@ Fixes since v1.7.10.3 * The message file for Swedish translation has been updated a bit. * A name taken from mailmap was copied into an internal buffer - incorrectly and could overun the buffer if it is too long. + incorrectly and could overrun the buffer if it is too long. * A malformed commit object that has a header line chomped in the middle could kill git with a NULL pointer dereference. diff --git a/Documentation/RelNotes/1.7.12.3.txt b/Documentation/RelNotes/1.7.12.3.txt index ecda427a35..4b822976b8 100644 --- a/Documentation/RelNotes/1.7.12.3.txt +++ b/Documentation/RelNotes/1.7.12.3.txt @@ -25,7 +25,7 @@ Fixes since v1.7.12.2 its Accept-Encoding header. * "git receive-pack" (the counterpart to "git push") did not give - progress output while processing objects it received to the puser + progress output while processing objects it received to the user when run over the smart-http protocol. * "git status" honored the ignore=dirty settings in .gitmodules but diff --git a/Documentation/RelNotes/1.7.5.3.txt b/Documentation/RelNotes/1.7.5.3.txt index 9c03353af2..1d24edcf2f 100644 --- a/Documentation/RelNotes/1.7.5.3.txt +++ b/Documentation/RelNotes/1.7.5.3.txt @@ -22,7 +22,7 @@ Fixes since v1.7.5.2 * "git log --stdin path" with an input that has additional pathspec used to corrupt memory. - * "git send-pack" (hence "git push") over smalt-HTTP protocol could + * "git send-pack" (hence "git push") over smart-HTTP protocol could deadlock when the client side pack-object died early. * Compressed tarball gitweb generates used to be made with the timestamp diff --git a/Documentation/RelNotes/1.8.0.txt b/Documentation/RelNotes/1.8.0.txt index 43883c14f0..63d6e4afa4 100644 --- a/Documentation/RelNotes/1.8.0.txt +++ b/Documentation/RelNotes/1.8.0.txt @@ -233,7 +233,7 @@ to them for details). together, misdetected branches. * "git receive-pack" (the counterpart to "git push") did not give - progress output while processing objects it received to the puser + progress output while processing objects it received to the user when run over the smart-http protocol. * When you misspell the command name you give to the "exec" action in diff --git a/Documentation/RelNotes/1.8.4.1.txt b/Documentation/RelNotes/1.8.4.1.txt index 96090ef599..c257beb114 100644 --- a/Documentation/RelNotes/1.8.4.1.txt +++ b/Documentation/RelNotes/1.8.4.1.txt @@ -15,7 +15,7 @@ Fixes since v1.8.4 in 1.8.4-rc1). * "git rebase -i" and other scripted commands were feeding a - random, data dependant error message to 'echo' and expecting it + random, data dependent error message to 'echo' and expecting it to come out literally. * Setting the "submodule.<name>.path" variable to the empty diff --git a/Documentation/RelNotes/1.8.4.txt b/Documentation/RelNotes/1.8.4.txt index 02f681b710..2e7529928b 100644 --- a/Documentation/RelNotes/1.8.4.txt +++ b/Documentation/RelNotes/1.8.4.txt @@ -58,7 +58,7 @@ Foreign interfaces, subsystems and ports. credential helper interface from Git.pm. * Update build for Cygwin 1.[57]. Torsten Bögershausen reports that - this is fine with Cygwin 1.7 ($gmane/225824) so let's try moving it + this is fine with Cygwin 1.7 (cf. <51A606A0.5060101@web.de>) so let's try moving it ahead. * The credential helper to talk to keychain on OS X (in contrib/) has @@ -365,7 +365,7 @@ details). (merge 2fbd4f9 mh/maint-lockfile-overflow later to maint). * Invocations of "git checkout" used internally by "git rebase" were - counted as "checkout", and affected later "git checkout -" to the + counted as "checkout", and affected later "git checkout -", which took the user to an unexpected place. (merge 3bed291 rr/rebase-checkout-reflog later to maint). diff --git a/Documentation/RelNotes/2.1.3.txt b/Documentation/RelNotes/2.1.3.txt index acc9ebb886..0dfb17c4fc 100644 --- a/Documentation/RelNotes/2.1.3.txt +++ b/Documentation/RelNotes/2.1.3.txt @@ -13,7 +13,7 @@ Git v2.1.3 Release Notes they are new enough to support the `--output` option. * "git pack-objects" forgot to disable the codepath to generate - object recheability bitmap when it needs to split the resulting + object reachability bitmap when it needs to split the resulting pack. * "gitweb" used deprecated CGI::startfrom, which was removed from diff --git a/Documentation/RelNotes/2.10.0.txt b/Documentation/RelNotes/2.10.0.txt index f4da28ab66..3792b7d03d 100644 --- a/Documentation/RelNotes/2.10.0.txt +++ b/Documentation/RelNotes/2.10.0.txt @@ -478,7 +478,7 @@ notes for details). * One part of "git am" had an oddball helper function that called stuff from outside "his" as opposed to calling what we have "ours", which was not gender-neutral and also inconsistent with the rest of - the system where outside stuff is usuall called "theirs" in + the system where outside stuff is usually called "theirs" in contrast to "ours". * "git blame file" allowed the lineage of lines in the uncommitted, diff --git a/Documentation/RelNotes/2.10.2.txt b/Documentation/RelNotes/2.10.2.txt index c4d4397023..abbd331508 100644 --- a/Documentation/RelNotes/2.10.2.txt +++ b/Documentation/RelNotes/2.10.2.txt @@ -86,7 +86,7 @@ Fixes since v2.10.1 by refusing to check out a branch that is already checked out in another worktree. However, this also prevented checking out a branch, which is designated as the primary branch of a bare - reopsitory, in a worktree that is connected to the bare + repository, in a worktree that is connected to the bare repository. The check has been corrected to allow it. * "git rebase" immediately after "git clone" failed to find the fork diff --git a/Documentation/RelNotes/2.11.1.txt b/Documentation/RelNotes/2.11.1.txt index 9cd14c8197..7d35cf186d 100644 --- a/Documentation/RelNotes/2.11.1.txt +++ b/Documentation/RelNotes/2.11.1.txt @@ -104,7 +104,7 @@ Fixes since v2.11 "git difftool --dir-diff" from a subdirectory never worked. This has been fixed. - * "git p4" that tracks multile p4 paths imported a single changelist + * "git p4" that tracks multiple p4 paths imported a single changelist that touches files in these multiple paths as one commit, followed by many empty commits. This has been fixed. diff --git a/Documentation/RelNotes/2.12.0.txt b/Documentation/RelNotes/2.12.0.txt index ef8b97da9b..d2f6a83614 100644 --- a/Documentation/RelNotes/2.12.0.txt +++ b/Documentation/RelNotes/2.12.0.txt @@ -315,7 +315,7 @@ notes for details). "git difftool --dir-diff" from a subdirectory never worked. This has been fixed. - * "git p4" that tracks multile p4 paths imported a single changelist + * "git p4" that tracks multiple p4 paths imported a single changelist that touches files in these multiple paths as one commit, followed by many empty commits. This has been fixed. diff --git a/Documentation/RelNotes/2.13.0.txt b/Documentation/RelNotes/2.13.0.txt index aa99d4b3ce..2a47b4cb0c 100644 --- a/Documentation/RelNotes/2.13.0.txt +++ b/Documentation/RelNotes/2.13.0.txt @@ -177,7 +177,7 @@ UI, Workflows & Features been changed to enable "--decorate". * The output from "git status --short" has been extended to show - various kinds of dirtyness in submodules differently; instead of to + various kinds of dirtiness in submodules differently; instead of to "M" for modified, 'm' and '?' can be shown to signal changes only to the working tree of the submodule but not the commit that is checked out. diff --git a/Documentation/RelNotes/2.13.3.txt b/Documentation/RelNotes/2.13.3.txt index 5d76ad5310..384e4de265 100644 --- a/Documentation/RelNotes/2.13.3.txt +++ b/Documentation/RelNotes/2.13.3.txt @@ -25,7 +25,7 @@ Fixes since v2.13.2 * The code to pick up and execute command alias definition from the configuration used to switch to the top of the working tree and then come back when the expanded alias was executed, which was - unnecessarilyl complex. Attempt to simplify the logic by using the + unnecessarily complex. Attempt to simplify the logic by using the early-config mechanism that does not chdir around. * "git add -p" were updated in 2.12 timeframe to cope with custom @@ -35,7 +35,7 @@ Fixes since v2.13.2 * Fix a recent regression to "git rebase -i" and add tests that would have caught it and others. - * An unaligned 32-bit access in pack-bitmap code ahs been corrected. + * An unaligned 32-bit access in pack-bitmap code has been corrected. * Tighten error checks for invalid "git apply" input. diff --git a/Documentation/RelNotes/2.14.0.txt b/Documentation/RelNotes/2.14.0.txt index 4246c68ff5..2711a2529d 100644 --- a/Documentation/RelNotes/2.14.0.txt +++ b/Documentation/RelNotes/2.14.0.txt @@ -141,7 +141,7 @@ Performance, Internal Implementation, Development Support etc. * Some platforms have ulong that is smaller than time_t, and our historical use of ulong for timestamp would mean they cannot represent some timestamp that the platform allows. Invent a - separate and dedicated timestamp_t (so that we can distingiuish + separate and dedicated timestamp_t (so that we can distinguish timestamps and a vanilla ulongs, which along is already a good move), and then declare uintmax_t is the type to be used as the timestamp_t. @@ -442,7 +442,7 @@ notes for details). * The code to pick up and execute command alias definition from the configuration used to switch to the top of the working tree and then come back when the expanded alias was executed, which was - unnecessarilyl complex. Attempt to simplify the logic by using the + unnecessarily complex. Attempt to simplify the logic by using the early-config mechanism that does not chdir around. * Fix configuration codepath to pay proper attention to commondir diff --git a/Documentation/RelNotes/2.16.0.txt b/Documentation/RelNotes/2.16.0.txt index 0c81c5915f..b474781ed8 100644 --- a/Documentation/RelNotes/2.16.0.txt +++ b/Documentation/RelNotes/2.16.0.txt @@ -407,7 +407,7 @@ Fixes since v2.15 (merge eef3df5a93 bw/pathspec-match-submodule-boundary later to maint). * Amending commits in git-gui broke the author name that is non-ascii - due to incorrect enconding conversion. + due to incorrect encoding conversion. * Recent update to the submodule configuration code broke "diff-tree" by accidentally stopping to read from the index upfront. diff --git a/Documentation/RelNotes/2.16.3.txt b/Documentation/RelNotes/2.16.3.txt index 64a0bcb0d2..f0121a8f2d 100644 --- a/Documentation/RelNotes/2.16.3.txt +++ b/Documentation/RelNotes/2.16.3.txt @@ -24,7 +24,7 @@ Fixes since v2.16.2 * The http tracing code, often used to debug connection issues, learned to redact potentially sensitive information from its output - so that it can be more safely sharable. + so that it can be more safely shareable. * Crash fix for a corner case where an error codepath tried to unlock what it did not acquire lock on. diff --git a/Documentation/RelNotes/2.17.0.txt b/Documentation/RelNotes/2.17.0.txt index c2cf891f71..8b17c26033 100644 --- a/Documentation/RelNotes/2.17.0.txt +++ b/Documentation/RelNotes/2.17.0.txt @@ -216,7 +216,7 @@ Fixes since v2.16 * The http tracing code, often used to debug connection issues, learned to redact potentially sensitive information from its output - so that it can be more safely sharable. + so that it can be more safely shareable. (merge 8ba18e6fa4 jt/http-redact-cookies later to maint). * Crash fix for a corner case where an error codepath tried to unlock diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.txt index 3ea280cf68..6c8a0e97c1 100644 --- a/Documentation/RelNotes/2.18.0.txt +++ b/Documentation/RelNotes/2.18.0.txt @@ -179,7 +179,7 @@ Performance, Internal Implementation, Development Support etc. (merge 00a3da2a13 nd/remove-ignore-env-field later to maint). * Code to find the length to uniquely abbreviate object names based - on packfile content, which is a relatively recent addtion, has been + on packfile content, which is a relatively recent addition, has been optimized to use the same fan-out table. * The mechanism to use parse-options API to automate the command line diff --git a/Documentation/RelNotes/2.19.0.txt b/Documentation/RelNotes/2.19.0.txt index a06ccf6e2a..891c79b9cb 100644 --- a/Documentation/RelNotes/2.19.0.txt +++ b/Documentation/RelNotes/2.19.0.txt @@ -106,7 +106,7 @@ Performance, Internal Implementation, Development Support etc. * The conversion to pass "the_repository" and then "a_repository" throughout the object access API continues. - * Continuing with the idea to programatically enumerate various + * Continuing with the idea to programmatically enumerate various pieces of data required for command line completion, teach the codebase to report the list of configuration variables subcommands care about to help complete them. diff --git a/Documentation/RelNotes/2.20.0.txt b/Documentation/RelNotes/2.20.0.txt index e71fe3dee1..3dd7e6e1fc 100644 --- a/Documentation/RelNotes/2.20.0.txt +++ b/Documentation/RelNotes/2.20.0.txt @@ -119,7 +119,7 @@ UI, Workflows & Features alias expansion. * The documentation of "git gc" has been updated to mention that it - is no longer limited to "pruning away crufts" but also updates + is no longer limited to "pruning away cruft" but also updates ancillary files like commit-graph as a part of repository optimization. diff --git a/Documentation/RelNotes/2.23.0.txt b/Documentation/RelNotes/2.23.0.txt new file mode 100644 index 0000000000..e3c4e78265 --- /dev/null +++ b/Documentation/RelNotes/2.23.0.txt @@ -0,0 +1,348 @@ +Git 2.23 Release Notes +====================== + +Updates since v2.22 +------------------- + +Backward compatibility note + + * The "--base" option of "format-patch" computed the patch-ids for + prerequisite patches in an unstable way, which has been updated to + compute in a way that is compatible with "git patch-id --stable". + + * The "git log" command by default behaves as if the --mailmap option + was given. + + +UI, Workflows & Features + + * The "git fast-export/import" pair has been taught to handle commits + with log messages in encoding other than UTF-8 better. + + * In recent versions of Git, per-worktree refs are exposed in + refs/worktrees/<wtname>/ hierarchy, which means that worktree names + must be a valid refname component. The code now sanitizes the names + given to worktrees, to make sure these refs are well-formed. + + * "git merge" learned "--quit" option that cleans up the in-progress + merge while leaving the working tree and the index still in a mess. + + * "git format-patch" learns a configuration to set the default for + its --notes=<ref> option. + + * The code to show args with potential typo that cannot be + interpreted as a commit-ish has been improved. + + * "git clone --recurse-submodules" learned to set up the submodules + to ignore commit object names recorded in the superproject gitlink + and instead use the commits that happen to be at the tip of the + remote-tracking branches from the get-go, by passing the new + "--remote-submodules" option. + + * The pattern "git diff/grep" use to extract funcname and words + boundary for Matlab has been extend to cover Octave, which is more + or less equivalent. + + * "git help git" was hard to discover (well, at least for some + people). + + * The pattern "git diff/grep" use to extract funcname and words + boundary for Rust has been added. + + * "git status" can be told a non-standard default value for the + "--[no-]ahead-behind" option with a new configuration variable + status.aheadBehind. + + * "git fetch" and "git pull" reports when a fetch results in + non-fast-forward updates to let the user notice unusual situation. + The commands learned "--no-show-forced-updates" option to disable + this safety feature. + + * Two new commands "git switch" and "git restore" are introduced to + split "checking out a branch to work on advancing its history" and + "checking out paths out of the index and/or a tree-ish to work on + advancing the current history" out of the single "git checkout" + command. + + * "git branch --list" learned to always output the detached HEAD as + the first item (when the HEAD is detached, of course), regardless + of the locale. + + * The conditional inclusion mechanism learned to base the choice on + the branch the HEAD currently is on. + + * "git rev-list --objects" learned the "--no-object-names" option to + squelch the path to the object that is used as a grouping hint for + pack-objects. + + * A new tag.gpgSign configuration variable turns "git tag -a" into + "git tag -s". + + * "git multi-pack-index" learned expire and repack subcommands. + + * "git blame" learned to "ignore" commits in the history, whose + effects (as well as their presence) get ignored. + + * "git cherry-pick/revert" learned a new "--skip" action. + + * The tips of refs from the alternate object store can be used as + starting point for reachability computation now. + + * Extra blank lines in "git status" output have been reduced. + + * The commits in a repository can be described by multiple + commit-graph files now, which allows the commit-graph files to be + updated incrementally. + + * "git range-diff" output has been tweaked for easier identification + of which part of what file the patch shown is about. + + +Performance, Internal Implementation, Development Support etc. + + * Update supporting parts of "git rebase" to remove code that should + no longer be used. + + * Developer support to emulate unsatisfied prerequisites in tests to + ensure that the remainder of the tests still succeeds when tests + with prerequisites are skipped. + + * "git update-server-info" learned not to rewrite the file with the + same contents. + + * The way of specifying the path to find dynamic libraries at runtime + has been simplified. The old default to pass -R/path/to/dir has been + replaced with the new default to pass -Wl,-rpath,/path/to/dir, + which is the more recent GCC uses. Those who need to build with an + old GCC can still use "CC_LD_DYNPATH=-R" + + * Prepare use of reachability index in topological walker that works + on a range (A..B). + + * A new tutorial targeting specifically aspiring git-core + developers has been added. + + * Auto-detect how to tell HP-UX aCC where to use dynamically linked + libraries from at runtime. + + * "git mergetool" and its tests now spawn fewer subprocesses. + + * Dev support update to help tracing out tests. + + * Support to build with MSVC has been updated. + + * "git fetch" that grabs from a group of remotes learned to run the + auto-gc only once at the very end. + + * A handful of Windows build patches have been upstreamed. + + * The code to read state files used by the sequencer machinery for + "git status" has been made more robust against a corrupt or stale + state files. + + * "git for-each-ref" with multiple patterns have been optimized. + + * The tree-walk API learned to pass an in-core repository + instance throughout more codepaths. + + * When one step in multi step cherry-pick or revert is reset or + committed, the command line prompt script failed to notice the + current status, which has been improved. + + * Many GIT_TEST_* environment variables control various aspects of + how our tests are run, but a few followed "non-empty is true, empty + or unset is false" while others followed the usual "there are a few + ways to spell true, like yes, on, etc., and also ways to spell + false, like no, off, etc." convention. + + * Adjust the dir-iterator API and apply it to the local clone + optimization codepath. + + * We have been trying out a few language features outside c89; the + coding guidelines document did not talk about them and instead had + a blanket ban against them. + + * A test helper has been introduced to optimize preparation of test + repositories with many simple commits, and a handful of test + scripts have been updated to use it. + + +Fixes since v2.22 +----------------- + + * A relative pathname given to "git init --template=<path> <repo>" + ought to be relative to the directory "git init" gets invoked in, + but it instead was made relative to the repository, which has been + corrected. + + * "git worktree add" used to fail when another worktree connected to + the same repository was corrupt, which has been corrected. + + * The ownership rule for the file descriptor to fast-import remote + backend was mixed up, leading to an unrelated file descriptor getting + closed, which has been fixed. + + * A "merge -c" instruction during "git rebase --rebase-merges" should + give the user a chance to edit the log message, even when there is + otherwise no need to create a new merge and replace the existing + one (i.e. fast-forward instead), but did not. Which has been + corrected. + + * Code cleanup and futureproof. + + * More parameter validation. + + * "git update-server-info" used to leave stale packfiles in its + output, which has been corrected. + + * The server side support for "git fetch" used to show incorrect + value for the HEAD symbolic ref when the namespace feature is in + use, which has been corrected. + + * "git am -i --resolved" segfaulted after trying to see a commit as + if it were a tree, which has been corrected. + + * "git bundle verify" needs to see if prerequisite objects exist in + the receiving repository, but the command did not check if we are + in a repository upfront, which has been corrected. + + * "git merge --squash" is designed to update the working tree and the + index without creating the commit, and this cannot be countermanded + by adding the "--commit" option; the command now refuses to work + when both options are given. + + * The data collected by fsmonitor was not properly written back to + the on-disk index file, breaking t7519 tests occasionally, which + has been corrected. + + * Update to Unicode 12.1 width table. + + * The command line to invoke a "git cat-file" command from inside + "git p4" was not properly quoted to protect a caret and running a + broken command on Windows, which has been corrected. + + * "git request-pull" learned to warn when the ref we ask them to pull + from in the local repository and in the published repository are + different. + + * When creating a partial clone, the object filtering criteria is + recorded for the origin of the clone, but this incorrectly used a + hardcoded name "origin" to name that remote; it has been corrected + to honor the "--origin <name>" option. + + * "git fetch" into a lazy clone forgot to fetch base objects that are + necessary to complete delta in a thin packfile, which has been + corrected. + + * The filter_data used in the list-objects-filter (which manages a + lazily sparse clone repository) did not use the dynamic array API + correctly---'nr' is supposed to point at one past the last element + of the array in use. This has been corrected. + + * The description about slashes in gitignore patterns (used to + indicate things like "anchored to this level only" and "only + matches directories") has been revamped. + + * The URL decoding code has been updated to avoid going past the end + of the string while parsing %-<hex>-<hex> sequence. + + * The list of for-each like macros used by clang-format has been + updated. + + * "git branch --list" learned to show branches that are checked out + in other worktrees connected to the same repository prefixed with + '+', similar to the way the currently checked out branch is shown + with '*' in front. + (merge 6e9381469e nb/branch-show-other-worktrees-head later to maint). + + * Code restructuring during 2.20 period broke fetching tags via + "import" based transports. + + * The commit-graph file is now part of the "files that the runtime + may keep open file descriptors on, all of which would need to be + closed when done with the object store", and the file descriptor to + an existing commit-graph file now is closed before "gc" finalizes a + new instance to replace it. + + * "git checkout -p" needs to selectively apply a patch in reverse, + which did not work well. + + * Code clean-up to avoid signed integer wraparounds during binary search. + + * "git interpret-trailers" always treated '#' as the comment + character, regardless of core.commentChar setting, which has been + corrected. + + * "git stash show 23" used to work, but no more after getting + rewritten in C; this regression has been corrected. + + * "git rebase --abort" used to leave refs/rewritten/ when concluding + "git rebase -r", which has been corrected. + + * An incorrect list of options was cached after command line + completion failed (e.g. trying to complete a command that requires + a repository outside one), which has been corrected. + + * The code to parse scaled numbers out of configuration files has + been made more robust and also easier to follow. + + * The codepath to compute delta islands used to spew progress output + without giving the callers any way to squelch it, which has been + fixed. + + * Protocol capabilities that go over wire should never be translated, + but it was incorrectly marked for translation, which has been + corrected. The output of protocol capabilities for debugging has + been tweaked a bit. + + * Use "Erase in Line" CSI sequence that is already used in the editor + support to clear cruft in the progress output. + + * "git submodule foreach" did not protect command line options passed + to the command to be run in each submodule correctly, when the + "--recursive" option was in use. + + * The configuration variable rebase.rescheduleFailedExec should be + effective only while running an interactive rebase and should not + affect anything when running a non-interactive one, which was not + the case. This has been corrected. + + * The "git clone" documentation refers to command line options in its + description in the short form; they have been replaced with long + forms to make them more recognisable. + + * Generation of pack bitmaps are now disabled when .keep files exist, + as these are mutually exclusive features. + (merge 7328482253 ew/repack-with-bitmaps-by-default later to maint). + + * "git rm" to resolve a conflicted path leaked an internal message + "needs merge" before actually removing the path, which was + confusing. This has been corrected. + + * "git stash --keep-index" did not work correctly on paths that have + been removed, which has been fixed. + (merge b932f6a5e8 tg/stash-keep-index-with-removed-paths later to maint). + + * Window 7 update ;-) + + * A codepath that reads from GPG for signed object verification read + past the end of allocated buffer, which has been fixed. + + * "git clean" silently skipped a path when it cannot lstat() it; now + it gives a warning. + + * "git push --atomic" that goes over the transport-helper (namely, + the smart http transport) failed to prevent refs to be pushed when + it can locally tell that one of the ref update will fail without + having to consult the other end, which has been corrected. + + * The internal diff machinery can be made to read out of bounds while + looking for --function-context line in a corner case, which has been + corrected. + (merge b777f3fd61 jk/xdiff-clamp-funcname-context-index later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge fbec05c210 cc/test-oidmap later to maint). + (merge 7a06fb038c jk/no-system-includes-in-dot-c later to maint). + (merge 81ed2b405c cb/xdiff-no-system-includes-in-dot-c later to maint). + (merge d61e6ce1dd sg/fsck-config-in-doc later to maint). diff --git a/Documentation/RelNotes/2.23.1.txt b/Documentation/RelNotes/2.23.1.txt new file mode 100644 index 0000000000..2083b492ce --- /dev/null +++ b/Documentation/RelNotes/2.23.1.txt @@ -0,0 +1,8 @@ +Git v2.23.1 Release Notes +========================= + +This release merges up the fixes that appear in v2.14.6, v2.15.4, +v2.17.3, v2.20.2 and in v2.21.1, addressing the security issues +CVE-2019-1348, CVE-2019-1349, CVE-2019-1350, CVE-2019-1351, +CVE-2019-1352, CVE-2019-1353, CVE-2019-1354, CVE-2019-1387, and +CVE-2019-19604; see the release notes for those versions for details. diff --git a/Documentation/RelNotes/2.23.2.txt b/Documentation/RelNotes/2.23.2.txt new file mode 100644 index 0000000000..b697cbe0e3 --- /dev/null +++ b/Documentation/RelNotes/2.23.2.txt @@ -0,0 +1,5 @@ +Git v2.23.2 Release Notes +========================= + +This release merges the security fix that appears in v2.17.4; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.23.3.txt b/Documentation/RelNotes/2.23.3.txt new file mode 100644 index 0000000000..2e35490137 --- /dev/null +++ b/Documentation/RelNotes/2.23.3.txt @@ -0,0 +1,5 @@ +Git v2.23.3 Release Notes +========================= + +This release merges the security fix that appears in v2.17.5; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.23.4.txt b/Documentation/RelNotes/2.23.4.txt new file mode 100644 index 0000000000..6e5424d0da --- /dev/null +++ b/Documentation/RelNotes/2.23.4.txt @@ -0,0 +1,7 @@ +Git v2.23.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4 and v2.22.5 to address the security +issue CVE-2021-21300; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.24.0.txt b/Documentation/RelNotes/2.24.0.txt new file mode 100644 index 0000000000..bde154124c --- /dev/null +++ b/Documentation/RelNotes/2.24.0.txt @@ -0,0 +1,398 @@ +Git 2.24 Release Notes +====================== + +Updates since v2.23 +------------------- + +Backward compatibility note + + * "filter-branch" is showing its age and alternatives are available. + From this release, we started to discourage its use and hint + people about filter-repo. + +UI, Workflows & Features + + * We now have an active interim maintainer for the Git-Gui part of + the system. Praise and thank Pratyush Yadav for volunteering. + + * The command line parser learned "--end-of-options" notation; the + standard convention for scripters to have hardcoded set of options + first on the command line, and force the command to treat end-user + input as non-options, has been to use "--" as the delimiter, but + that would not work for commands that use "--" as a delimiter + between revs and pathspec. + + * A mechanism to affect the default setting for a (related) group of + configuration variables is introduced. + + * "git fetch" learned "--set-upstream" option to help those who first + clone from their private fork they intend to push to, add the true + upstream via "git remote add" and then "git fetch" from it. + + * Device-tree files learned their own userdiff patterns. + (merge 3c81760bc6 sb/userdiff-dts later to maint). + + * "git rebase --rebase-merges" learned to drive different merge + strategies and pass strategy specific options to them. + + * A new "pre-merge-commit" hook has been introduced. + + * Command line completion updates for "git -c var.name=val" have been + added. + + * The lazy clone machinery has been taught that there can be more + than one promisor remote and consult them in order when downloading + missing objects on demand. + + * The list-objects-filter API (used to create a sparse/lazy clone) + learned to take a combined filter specification. + + * The documentation and tests for "git format-patch" have been + cleaned up. + + * On Windows, the root level of UNC share is now allowed to be used + just like any other directory. + + * The command line completion support (in contrib/) learned about the + "--skip" option of "git revert" and "git cherry-pick". + + * "git rebase --keep-base <upstream>" tries to find the original base + of the topic being rebased and rebase on top of that same base, + which is useful when running the "git rebase -i" (and its limited + variant "git rebase -x"). + + The command also has learned to fast-forward in more cases where it + can instead of replaying to recreate identical commits. + + * A configuration variable tells "git fetch" to write the commit + graph after finishing. + + * "git add -i" has been taught to show the total number of hunks and + the hunks that has been processed so far when showing prompts. + + * "git fetch --jobs=<n>" allowed <n> parallel jobs when fetching + submodules, but this did not apply to "git fetch --multiple" that + fetches from multiple remote repositories. It now does. + + * The installation instruction for zsh completion script (in + contrib/) has been a bit improved. + + +Performance, Internal Implementation, Development Support etc. + + * The code to write commit-graph over given commit object names has + been made a bit more robust. + + * The first line of verbose output from each test piece now carries + the test name and number to help scanning with eyeballs. + + * Further clean-up of the initialization code. + + * xmalloc() used to have a mechanism to ditch memory and address + space resources as the last resort upon seeing an allocation + failure from the underlying malloc(), which made the code complex + and thread-unsafe with dubious benefit, as major memory resource + users already do limit their uses with various other mechanisms. + It has been simplified away. + + * Unnecessary full-tree diff in "git log -L" machinery has been + optimized away. + + * The http transport lacked some optimization the native transports + learned to avoid unnecessary ref advertisement, which has been + corrected. + + * Preparation for SHA-256 upgrade continues in the test department. + (merge 0c37c41d13 bc/hash-independent-tests-part-5 later to maint). + + * The memory ownership model of the "git fast-import" got + straightened out. + + * Output from trace2 subsystem is formatted more prettily now. + + * The internal code originally invented for ".gitignore" processing + got reshuffled and renamed to make it less tied to "excluding" and + stress more that it is about "matching", as it has been reused for + things like sparse checkout specification that want to check if a + path is "included". + + * "git stash" learned to write refreshed index back to disk. + + * Coccinelle checks are done on more source files than before now. + + * The cache-tree code has been taught to be less aggressive in + attempting to see if a tree object it computed already exists in + the repository. + + * The code to parse and use the commit-graph file has been made more + robust against corrupted input. + + * The hg-to-git script (in contrib/) has been updated to work with + Python 3. + + * Update the way build artifacts in t/helper/ directory are ignored. + + * Preparation for SHA-256 upgrade continues. + + * "git log --graph" for an octopus merge is sometimes colored + incorrectly, which is demonstrated and documented but not yet + fixed. + + * The trace2 output, when sending them to files in a designated + directory, can populate the directory with too many files; a + mechanism is introduced to set the maximum number of files and + discard further logs when the maximum is reached. + + * We have adopted a Code-of-conduct document. + (merge 3f9ef874a7 jk/coc later to maint). + + +Fixes since v2.23 +----------------- + + * "git grep --recurse-submodules" that looks at the working tree + files looked at the contents in the index in submodules, instead of + files in the working tree. + (merge 6a289d45c0 mt/grep-submodules-working-tree later to maint). + + * Codepaths to walk tree objects have been audited for integer + overflows and hardened. + (merge 5aa02f9868 jk/tree-walk-overflow later to maint). + + * "git pack-refs" can lose refs that are created while running, which + is getting corrected. + (merge a613d4f817 sc/pack-refs-deletion-racefix later to maint). + + * "git checkout" and "git restore" to re-populate the index from a + tree-ish (typically HEAD) did not work correctly for a path that + was removed and then added again with the intent-to-add bit, when + the corresponding working tree file was empty. This has been + corrected. + + * Compilation fix. + (merge 70597e8386 rs/nedalloc-fixlets later to maint). + + * "git gui" learned to call the clean-up procedure before exiting. + (merge 0d88f3d2c5 py/git-gui-do-quit later to maint). + + * We promoted the "indent heuristics" that decides where to split + diff hunks from experimental to the default a few years ago, but + some stale documentation still marked it as experimental, which has + been corrected. + (merge 64e5e1fba1 sg/diff-indent-heuristic-non-experimental later to maint). + + * Fix a mismerge that happened in 2.22 timeframe. + (merge acb7da05ac en/checkout-mismerge-fix later to maint). + + * "git archive" recorded incorrect length in extended pax header in + some corner cases, which has been corrected. + (merge 71d41ff651 rs/pax-extended-header-length-fix later to maint). + + * On-demand object fetching in lazy clone incorrectly tried to fetch + commits from submodule projects, while still working in the + superproject, which has been corrected. + (merge a63694f523 jt/diff-lazy-fetch-submodule-fix later to maint). + + * Prepare get_short_oid() codepath to be thread-safe. + (merge 7cfcb16b0e rs/sort-oid-array-thread-safe later to maint). + + * "for-each-ref" and friends that show refs did not protect themselves + against ancient tags that did not record tagger names when asked to + show "%(taggername)", which have been corrected. + (merge 8b3f33ef11 mp/for-each-ref-missing-name-or-email later to maint). + + * The "git am" based backend of "git rebase" ignored the result of + updating ".gitattributes" done in one step when replaying + subsequent steps. + (merge 2c65d90f75 bc/reread-attributes-during-rebase later to maint). + + * Tell cURL library to use the same malloc() implementation, with the + xmalloc() wrapper, as the rest of the system, for consistency. + (merge 93b980e58f cb/curl-use-xmalloc later to maint). + + * Build fix to adjust .gitignore to unignore a path that we started to track. + (merge aac6ff7b5b js/visual-studio later to maint). + + * A few implementation fixes in the notes API. + (merge 60fe477a0b mh/notes-duplicate-entries later to maint). + + * Fix an earlier regression to "git push --all" which should have + been forbidden when the target remote repository is set to be a + mirror. + (merge 8e4c8af058 tg/push-all-in-mirror-forbidden later to maint). + + * Fix an earlier regression in the test suite, which mistakenly + stopped running HTTPD tests. + (merge 3960290675 sg/git-test-boolean later to maint). + + * "git rebase --autostash <upstream> <branch>", when <branch> is + different from the current branch, incorrectly moved the tip of the + current branch, which has been corrected. + (merge bf1e28e0ad bw/rebase-autostash-keep-current-branch later to maint). + + * Update support for Asciidoctor documentation toolchain. + (merge 83b0b8953e ma/asciidoctor-refmiscinfo later to maint). + + * Start using DocBook 5 (instead of DocBook 4.5) as Asciidoctor 2.0 + no longer works with the older one. + (merge f6461b82b9 bc/doc-use-docbook-5 later to maint). + + * The markup used in user-manual has been updated to work better with + asciidoctor. + (merge c4d2f6143a ma/user-manual-markup-update later to maint). + + * Make sure the grep machinery does not abort when seeing a payload + that is not UTF-8 even when JIT is not in use with PCRE1. + (merge ad7c543e3b cb/skip-utf8-check-with-pcre1 later to maint). + + * The name of the blob object that stores the filter specification + for sparse cloning/fetching was interpreted in a wrong place in the + code, causing Git to abort. + + * "git log --decorate-refs-exclude=<pattern>" was incorrectly + overruled when the "--simplify-by-decoration" option is used, which + has been corrected. + (merge 0cc7380d88 rs/simplify-by-deco-with-deco-refs-exclude later to maint). + + * The "upload-pack" (the counterpart of "git fetch") needs to disable + commit-graph when responding to a shallow clone/fetch request, but + the way this was done made Git panic, which has been corrected. + + * The object traversal machinery has been optimized not to load tree + objects when we are only interested in commit history. + (merge 72ed80c784 jk/list-objects-optim-wo-trees later to maint). + + * The object name parser for "Nth parent" syntax has been made more + robust against integer overflows. + (merge 59fa5f5a25 rs/nth-parent-parse later to maint). + + * The code used in following tags in "git fetch" has been optimized. + (merge b7e2d8bca5 ms/fetch-follow-tag-optim later to maint). + + * Regression fix for progress output. + (merge 2bb74b53a4 sg/progress-fix later to maint). + + * A bug in merge-recursive code that triggers when a branch with a + symbolic link is merged with a branch that replaces it with a + directory has been fixed. + (merge 83e3ad3b12 jt/merge-recursive-symlink-is-not-a-dir-in-way later to maint). + + * The rename detection logic sorts a list of rename source candidates + by similarity to pick the best candidate, which means that a tie + between sources with the same similarity is broken by the original + location in the original candidate list (which is sorted by path). + Force the sorting by similarity done with a stable sort, which is + not promised by system supplied qsort(3), to ensure consistent + results across platforms. + (merge 2049b8dc65 js/diff-rename-force-stable-sort later to maint). + + * The code to skip "UTF" and "UTF-" prefix, when computing an advice + message, did not work correctly when the prefix was "UTF", which + has been fixed. + (merge b181676ce9 rs/convert-fix-utf-without-dash later to maint). + + * The author names taken from SVN repositories may have extra leading + or trailing whitespaces, which are now munged away. + (merge 4ddd4bddb1 tk/git-svn-trim-author-name later to maint). + + * "git rebase -i" showed a wrong HEAD while "reword" open the editor. + (merge b0a3186140 pw/rebase-i-show-HEAD-to-reword later to maint). + + * A few simplification and bugfixes to PCRE interface. + (merge c581e4a749 ab/pcre-jit-fixes later to maint). + + * PCRE fixes. + (merge ff61681b46 cb/pcre1-cleanup later to maint). + + * "git range-diff" segfaulted when diff.noprefix configuration was + used, as it blindly expected the patch it internally generates to + have the standard a/ and b/ prefixes. The command now forces the + internal patch to be built without any prefix, not to be affected + by any end-user configuration. + (merge 937b76ed49 js/range-diff-noprefix later to maint). + + * "git stash apply" in a subdirectory of a secondary worktree failed + to access the worktree correctly, which has been corrected. + (merge dfd557c978 js/stash-apply-in-secondary-worktree later to maint). + + * The merge-recursive machinery is one of the most complex parts of + the system that accumulated cruft over time. This large series + cleans up the implementation quite a bit. + (merge b657047719 en/merge-recursive-cleanup later to maint). + + * Pretty-printed command line formatter (used in e.g. reporting the + command being run by the tracing API) had a bug that lost an + argument that is an empty string, which has been corrected. + (merge ce2d7ed2fd gs/sq-quote-buf-pretty later to maint). + + * "git range-diff" failed to handle mode-only change, which has been + corrected. + (merge 2b6a9b13ca tg/range-diff-output-update later to maint). + + * Dev support update. + (merge 4f3c1dc5d6 dl/allow-running-cocci-verbosely later to maint). + + * "git format-patch -o <outdir>" did an equivalent of "mkdir <outdir>" + not "mkdir -p <outdir>", which was corrected. + + * "git stash save" lost local changes to submodules, which has been + corrected. + (merge 556895d0c8 jj/stash-reset-only-toplevel later to maint). + + * The atomic push over smart HTTP transport did not work, which has + been corrected. + (merge 6f1194246a bc/smart-http-atomic-push later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge d1387d3895 en/fast-import-merge-doc later to maint). + (merge 1c24a54ea4 bm/repository-layout-typofix later to maint). + (merge 415b770b88 ds/midx-expire-repack later to maint). + (merge 19800bdc3f nd/diff-parseopt later to maint). + (merge 58166c2e9d tg/t0021-racefix later to maint). + (merge 7027f508c7 dl/compat-cleanup later to maint). + (merge e770fbfeff jc/test-cleanup later to maint). + (merge 1fd881d404 rs/trace2-dst-warning later to maint). + (merge 7e92756751 mh/http-urlmatch-cleanup later to maint). + (merge 9784f97321 mh/release-commit-memory-fix later to maint). + (merge 60d198d022 tb/banned-vsprintf-namefix later to maint). + (merge 80e3658647 rs/help-unknown-ref-does-not-return later to maint). + (merge 0a8bc7068f dt/remote-helper-doc-re-lock-option later to maint). + (merge 27fd1e4ea7 en/merge-options-ff-and-friends later to maint). + (merge 502c386ff9 sg/clean-nested-repo-with-ignored later to maint). + (merge 26e3d1cbea am/mailmap-andrey-mazo later to maint). + (merge 47b27c96fa ss/get-time-cleanup later to maint). + (merge dd2e50a84e jk/commit-graph-cleanup later to maint). + (merge 4fd39c76e6 cs/pretty-formats-doc-typofix later to maint). + (merge 40e747e89d dl/submodule-set-branch later to maint). + (merge 689a146c91 rs/commit-graph-use-list-count later to maint). + (merge 0eb7c37a8a js/doc-patch-text later to maint). + (merge 4b3aa170d1 rs/nth-switch-code-simplification later to maint). + (merge 0d4304c124 ah/doc-submodule-ignore-submodules later to maint). + (merge af78249463 cc/svn-fe-py-shebang later to maint). + (merge 7bd97d6dff rs/alias-use-copy-array later to maint). + (merge c46ebc2496 sg/travis-help-debug later to maint). + (merge 24c681794f ps/my-first-contribution-alphasort later to maint). + (merge 75b2c15435 cb/do-not-use-test-cmp-with-a later to maint). + (merge cda0d497e3 bw/submodule-helper-usage-fix later to maint). + (merge fe0ed5d5e9 am/visual-studio-config-fix later to maint). + (merge 2e09c01232 sg/name-rev-cutoff-underflow-fix later to maint). + (merge ddb3c856f3 as/shallow-slab-use-fix later to maint). + (merge 71f4960b91 js/mingw-spawn-with-spaces-in-path later to maint). + (merge 53d687bf5f ah/cleanups later to maint). + (merge f537485fa5 rs/test-remove-useless-debugging-cat later to maint). + (merge 11a3d3aadd dl/rev-list-doc-cleanup later to maint). + (merge d928a8388a am/t0028-utf16-tests later to maint). + (merge b05b40930e dl/t0000-skip-test-test later to maint). + (merge 03d3b1297c js/xdiffi-comment-updates later to maint). + (merge 57d8f4b4c7 js/doc-stash-save later to maint). + (merge 8c1cfd58e3 ta/t1308-typofix later to maint). + (merge fa364ad790 bb/utf8-wcwidth-cleanup later to maint). + (merge 68b69211b2 bb/compat-util-comment-fix later to maint). + (merge 5cc6a4be11 rs/http-push-simplify later to maint). + (merge a81e42d235 rs/column-use-utf8-strnwidth later to maint). + (merge 062a309d36 rs/remote-curl-use-argv-array later to maint). + (merge 3b3c79f6c9 nr/diff-highlight-indent-fix later to maint). + (merge 3444ec2eb2 wb/fsmonitor-bitmap-fix later to maint). + (merge 10da030ab7 cb/pcre2-chartables-leakfix later to maint). + (merge 60e6569a12 js/mingw-needs-hiding-fix later to maint). + (merge 52bd3e4657 rl/gitweb-blame-prev-fix later to maint). diff --git a/Documentation/RelNotes/2.24.1.txt b/Documentation/RelNotes/2.24.1.txt new file mode 100644 index 0000000000..18104850fe --- /dev/null +++ b/Documentation/RelNotes/2.24.1.txt @@ -0,0 +1,8 @@ +Git v2.24.1 Release Notes +========================= + +This release merges up the fixes that appear in v2.14.6, v2.15.4, +v2.17.3, v2.20.2 and in v2.21.1, addressing the security issues +CVE-2019-1348, CVE-2019-1349, CVE-2019-1350, CVE-2019-1351, +CVE-2019-1352, CVE-2019-1353, CVE-2019-1354, CVE-2019-1387, and +CVE-2019-19604; see the release notes for those versions for details. diff --git a/Documentation/RelNotes/2.24.2.txt b/Documentation/RelNotes/2.24.2.txt new file mode 100644 index 0000000000..0049f65503 --- /dev/null +++ b/Documentation/RelNotes/2.24.2.txt @@ -0,0 +1,5 @@ +Git v2.24.2 Release Notes +========================= + +This release merges the security fix that appears in v2.17.4; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.24.3.txt b/Documentation/RelNotes/2.24.3.txt new file mode 100644 index 0000000000..5302e0f73b --- /dev/null +++ b/Documentation/RelNotes/2.24.3.txt @@ -0,0 +1,5 @@ +Git v2.24.3 Release Notes +========================= + +This release merges the security fix that appears in v2.17.5; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.24.4.txt b/Documentation/RelNotes/2.24.4.txt new file mode 100644 index 0000000000..4e216eec2a --- /dev/null +++ b/Documentation/RelNotes/2.24.4.txt @@ -0,0 +1,7 @@ +Git v2.24.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5 and v2.23.4 to address the +security issue CVE-2021-21300; see the release notes for these +versions for details. diff --git a/Documentation/RelNotes/2.25.0.txt b/Documentation/RelNotes/2.25.0.txt new file mode 100644 index 0000000000..91ceb34927 --- /dev/null +++ b/Documentation/RelNotes/2.25.0.txt @@ -0,0 +1,370 @@ +Git 2.25 Release Notes +====================== + +Updates since v2.24 +------------------- + +Backward compatibility notes + + +UI, Workflows & Features + + * A tutorial on object enumeration has been added. + + * The branch description ("git branch --edit-description") has been + used to fill the body of the cover letters by the format-patch + command; this has been enhanced so that the subject can also be + filled. + + * "git rebase --preserve-merges" has been marked as deprecated; this + release stops advertising it in the "git rebase -h" output. + + * The code to generate multi-pack index learned to show (or not to + show) progress indicators. + + * "git apply --3way" learned to honor merge.conflictStyle + configuration variable, like merges would. + + * The custom format for "git log --format=<format>" learned the l/L + placeholder that is similar to e/E that fills in the e-mail + address, but only the local part on the left side of '@'. + + * Documentation pages for "git shortlog" now list commit limiting + options explicitly. + + * The patterns to detect function boundary for Elixir language has + been added. + + * The completion script (in contrib/) learned that the "--onto" + option of "git rebase" can take its argument as the value of the + option. + + * The userdiff machinery has been taught that "async def" is another + way to begin a "function" in Python. + + * "git range-diff" learned to take the "--notes=<ref>" and the + "--no-notes" options to control the commit notes included in the + log message that gets compared. + + * "git rev-parse --show-toplevel" run outside of any working tree did + not error out, which has been corrected. + + * A few commands learned to take the pathspec from the standard input + or a named file, instead of taking it as the command line + arguments, with the "--pathspec-from-file" option. + + * "git submodule" learned a subcommand "set-url". + + * "git log" family learned "--pretty=reference" that gives the name + of a commit in the format that is often used to refer to it in log + messages. + + * The interaction between "git clone --recurse-submodules" and + alternate object store was ill-designed. The documentation and + code have been taught to make more clear recommendations when the + users see failures. + + * Management of sparsely checked-out working tree has gained a + dedicated "sparse-checkout" command. + + * Miscellaneous small UX improvements on "git-p4". + + * "git sparse-checkout list" subcommand learned to give its output in + a more concise form when the "cone" mode is in effect. + + +Performance, Internal Implementation, Development Support etc. + + * Debugging support for lazy cloning has been a bit improved. + + * Move the definition of a set of bitmask constants from 0ctal + literal to (1U<<count) notation. + + * Test updates to prepare for SHA-2 transition continues. + + * Crufty code and logic accumulated over time around the object + parsing and low-level object access used in "git fsck" have been + cleaned up. + + * The implementation of "git log --graph" got refactored and then its + output got simplified. + + * Follow recent push to move API docs from Documentation/ to header + files and update config.h + + * "git bundle" has been taught to use the parse options API. "git + bundle verify" learned "--quiet" and "git bundle create" learned + options to control the progress output. + + * Handling of commit objects that use non UTF-8 encoding during + "rebase -i" has been improved. + + * The beginning of rewriting "git add -i" in C. + + * A label used in the todo list that are generated by "git rebase + --rebase-merges" is used as a part of a refname; the logic to come + up with the label has been tightened to avoid names that cannot be + used as such. + + * The logic to avoid duplicate label names generated by "git rebase + --rebase-merges" forgot that the machinery itself uses "onto" as a + label name, which must be avoided by auto-generated labels, which + has been corrected. + + * We have had compatibility fallback macro definitions for "PRIuMAX", + "PRIu32", etc. but did not for "PRIdMAX", while the code used the + last one apparently without any hiccup reported recently. The + fallback macro definitions for these <inttypes.h> macros that must + appear in C99 systems have been removed. + + * Recently we have declared that GIT_TEST_* variables take the + usual boolean values (it used to be that some used "non-empty + means true" and taking GIT_TEST_VAR=YesPlease as true); make + sure we notice and fail when non-bool strings are given to + these variables. + + * Users of oneway_merge() (like "reset --hard") learned to take + advantage of fsmonitor to avoid unnecessary lstat(2) calls. + + * Performance tweak on "git push" into a repository with many refs + that point at objects we have never heard of. + + * PerfTest fix to avoid stale result mixed up with the latest round + of test results. + + * Hide lower-level verify_signed-buffer() API as a pure helper to + implement the public check_signature() function, in order to + encourage new callers to use the correct and more strict + validation. + + * Unnecessary reading of state variables back from the disk during + sequencer operation has been reduced. + + * The code has been made to avoid gmtime() and localtime() and prefer + their reentrant counterparts. + + * In a repository with many packfiles, the cost of the procedure that + avoids registering the same packfile twice was unnecessarily high + by using an inefficient search algorithm, which has been corrected. + + * Redo "git name-rev" to avoid recursive calls. + + * FreeBSD CI support via Cirrus-CI has been added. + + +Fixes since v2.24 +----------------- + + * "rebase -i" ceased to run post-commit hook by mistake in an earlier + update, which has been corrected. + + * "git notes copy $original" ought to copy the notes attached to the + original object to HEAD, but a mistaken tightening to command line + parameter validation made earlier disabled that feature by mistake. + + * When all files from some subdirectory were renamed to the root + directory, the directory rename heuristics would fail to detect that + as a rename/merge of the subdirectory to the root directory, which has + been corrected. + + * Code clean-up and a bugfix in the logic used to tell worktree local + and repository global refs apart. + (merge f45f88b2e4 sg/dir-trie-fixes later to maint). + + * "git stash save" in a working tree that is sparsely checked out + mistakenly removed paths that are outside the area of interest. + (merge 4a58c3d7f7 js/update-index-ignore-removal-for-skip-worktree later to maint). + + * "git rev-parse --git-path HEAD.lock" did not give the right path + when run in a secondary worktree. + (merge 76a53d640f js/git-path-head-dot-lock-fix later to maint). + + * "git merge --no-commit" needs "--no-ff" if you do not want to move + HEAD, which has been corrected in the manual page for "git bisect". + (merge 8dd327b246 ma/bisect-doc-sample-update later to maint). + + * "git worktree add" internally calls "reset --hard" that should not + descend into submodules, even when submodule.recurse configuration + is set, but it was affected. This has been corrected. + (merge 4782cf2ab6 pb/no-recursive-reset-hard-in-worktree-add later to maint). + + * Messages from die() etc. can be mixed up from multiple processes + without even line buffering on Windows, which has been worked + around. + (merge 116d1fa6c6 js/vreportf-wo-buffering later to maint). + + * HTTP transport had possible allocator/deallocator mismatch, which + has been corrected. + + * The watchman integration for fsmonitor was racy, which has been + corrected to be more conservative. + (merge dd0b61f577 kw/fsmonitor-watchman-fix later to maint). + + * Fetching from multiple remotes into the same repository in parallel + had a bad interaction with the recent change to (optionally) update + the commit-graph after a fetch job finishes, as these parallel + fetches compete with each other. Which has been corrected. + + * Recent update to "git stash pop" made the command empty the index + when run with the "--quiet" option, which has been corrected. + + * "git fetch" codepath had a big "do not lazily fetch missing objects + when I ask if something exists" switch. This has been corrected by + marking the "does this thing exist?" calls with "if not please do not + lazily fetch it" flag. + + * Test update to avoid wasted cycles. + (merge e0316695ec sg/skip-skipped-prereq later to maint). + + * Error handling after "git push" finishes sending the packdata and + waits for the response to the remote side has been improved. + (merge ad7a403268 jk/send-pack-remote-failure later to maint). + + * Some codepaths in "gitweb" that forgot to escape URLs generated + based on end-user input have been corrected. + (merge a376e37b2c jk/gitweb-anti-xss later to maint). + + * CI jobs for macOS has been made less chatty when updating perforce + package used during testing. + (merge 0dbc4a0edf jc/azure-ci-osx-fix-fix later to maint). + + * "git unpack-objects" used to show progress based only on the number + of received and unpacked objects, which stalled when it has to + handle an unusually large object. It now shows the throughput as + well. + (merge bae60ba7e9 sg/unpack-progress-throughput later to maint). + + * The sequencer machinery compared the HEAD and the state it is + attempting to commit to decide if the result would be a no-op + commit, even when amending a commit, which was incorrect, and + has been corrected. + + * The code to parse GPG output used to assume incorrectly that the + finterprint for the primary key would always be present for a valid + signature, which has been corrected. + (merge 67a6ea6300 hi/gpg-optional-pkfp-fix later to maint). + + * "git submodule status" and "git submodule status --cached" show + different things, but the documentation did not cover them + correctly, which has been corrected. + (merge 8d483c8408 mg/doc-submodule-status-cached later to maint). + + * "git reset --patch $object" without any pathspec should allow a + tree object to be given, but incorrectly required a committish, + which has been corrected. + + * "git submodule status" that is run from a subdirectory of the + superproject did not work well, which has been corrected. + (merge 1f3aea22c7 mg/submodule-status-from-a-subdirectory later to maint). + + * The revision walking machinery uses resources like per-object flag + bits that need to be reset before a new iteration of walking + begins, but the resources related to topological walk were not + cleared correctly, which has been corrected. + (merge 0aa0c2b2ec mh/clear-topo-walk-upon-reset later to maint). + + * TravisCI update. + (merge 176441bfb5 sg/osx-force-gcc-9 later to maint). + + * While running "revert" or "cherry-pick --edit" for multiple + commits, a recent regression incorrectly detected "nothing to + commit, working tree clean", instead of replaying the commits, + which has been corrected. + (merge befd4f6a81 sg/assume-no-todo-update-in-cherry-pick later to maint). + + * Work around a issue where a FD that is left open when spawning a + child process and is kept open in the child can interfere with the + operation in the parent process on Windows. + + * One kind of progress messages were always given during commit-graph + generation, instead of following the "if it takes more than two + seconds, show progress" pattern, which has been corrected. + + * "git rebase" did not work well when format.useAutoBase + configuration variable is set, which has been corrected. + + * The "diff" machinery learned not to lose added/removed blank lines + in the context when --ignore-blank-lines and --function-context are + used at the same time. + (merge 0bb313a552 rs/xdiff-ignore-ws-w-func-context later to maint). + + * The test on "fast-import" used to get stuck when "fast-import" died + in the middle. + (merge 0d9b0d7885 sg/t9300-robustify later to maint). + + * "git format-patch" can take a set of configured format.notes values + to specify which notes refs to use in the log message part of the + output. The behaviour of this was not consistent with multiple + --notes command line options, which has been corrected. + (merge e0f9095aaa dl/format-patch-notes-config-fixup later to maint). + + * "git p4" used to ignore lfs.storage configuration variable, which + has been corrected. + (merge ea94b16fb8 rb/p4-lfs later to maint). + + * Assorted fixes to the directory traversal API. + (merge 6836d2fe06 en/fill-directory-fixes later to maint). + + * Forbid pathnames that the platform's filesystem cannot represent on + MinGW. + (merge 4dc42c6c18 js/mingw-reserved-filenames later to maint). + + * "git rebase --signoff" stopped working when the command was written + in C, which has been corrected. + (merge 4fe7e43c53 en/rebase-signoff-fix later to maint). + + * An earlier update to Git for Windows declared that a tree object is + invalid if it has a path component with backslash in it, which was + overly strict, which has been corrected. The only protection the + Windows users need is to prevent such path (or any path that their + filesystem cannot check out) from entering the index. + (merge 224c7d70fa js/mingw-loosen-overstrict-tree-entry-checks later to maint). + + * The code to write split commit-graph file(s) upon fetching computed + bogus value for the parameter used in splitting the resulting + files, which has been corrected. + (merge 63020f175f ds/commit-graph-set-size-mult later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 80736d7c5e jc/am-show-current-patch-docfix later to maint). + (merge 8b656572ca sg/commit-graph-usage-fix later to maint). + (merge 6c02042139 mr/clone-dir-exists-to-path-exists later to maint). + (merge 44ae131e38 sg/blame-indent-heuristics-is-now-the-default later to maint). + (merge 0115e5d929 dl/doc-diff-no-index-implies-exit-code later to maint). + (merge 270de6acbe en/t6024-style later to maint). + (merge 14c4776d75 ns/test-desc-typofix later to maint). + (merge 68d40f30c4 dj/typofix-merge-strat later to maint). + (merge f66e0401ab jk/optim-in-pack-idx-conversion later to maint). + (merge 169bed7421 rs/parse-options-dup-null-fix later to maint). + (merge 51bd6be32d rs/use-copy-array-in-mingw-shell-command-preparation later to maint). + (merge b018719927 ma/t7004 later to maint). + (merge 932757b0cc ar/install-doc-update-cmds-needing-the-shell later to maint). + (merge 46efd28be1 ep/guard-kset-tar-headers later to maint). + (merge 9e5afdf997 ec/fetch-mark-common-refs-trace2 later to maint). + (merge f0e58b3fe8 pb/submodule-update-fetches later to maint). + (merge 2a02262078 dl/t5520-cleanup later to maint). + (merge a4fb016ba1 js/pkt-line-h-typofix later to maint). + (merge 54a7a64613 rs/simplify-prepare-cmd later to maint). + (merge 3eae30e464 jk/lore-is-the-archive later to maint). + (merge 14b7664df8 dl/lore-is-the-archive later to maint). + (merge 0e40a73a4c po/bundle-doc-clonable later to maint). + (merge e714b898c6 as/t7812-missing-redirects-fix later to maint). + (merge 528d9e6d01 jk/perf-wo-git-dot-pm later to maint). + (merge fc42f20e24 sg/test-squelch-noise-in-commit-bulk later to maint). + (merge c64368e3a2 bc/t9001-zsh-in-posix-emulation-mode later to maint). + (merge 11de8dd7ef dr/branch-usage-casefix later to maint). + (merge e05e8cf074 rs/archive-zip-code-cleanup later to maint). + (merge 147ee35558 rs/commit-export-env-simplify later to maint). + (merge 4507ecc771 rs/patch-id-use-oid-to-hex later to maint). + (merge 51a0a4ed95 mr/bisect-use-after-free later to maint). + (merge cc2bd5c45d pb/submodule-doc-xref later to maint). + (merge df5be01669 ja/doc-markup-cleanup later to maint). + (merge 7c5cea7242 mr/bisect-save-pointer-to-const-string later to maint). + (merge 20a67e8ce9 js/use-test-tool-on-path later to maint). + (merge 4e61b2214d ew/packfile-syscall-optim later to maint). + (merge ace0f86c7f pb/clarify-line-log-doc later to maint). + (merge 763a59e71c en/merge-recursive-oid-eq-simplify later to maint). + (merge 4e2c4c0d4f do/gitweb-typofix-in-comments later to maint). + (merge 421c0ffb02 jb/doc-multi-pack-idx-fix later to maint). + (merge f8740c586b pm/am-in-body-header-doc-update later to maint). + (merge 5814d44d9b tm/doc-submodule-absorb-fix later to maint). diff --git a/Documentation/RelNotes/2.25.1.txt b/Documentation/RelNotes/2.25.1.txt new file mode 100644 index 0000000000..cd869b02bb --- /dev/null +++ b/Documentation/RelNotes/2.25.1.txt @@ -0,0 +1,55 @@ +Git 2.25.1 Release Notes +======================== + +Fixes since v2.25 +----------------- + + * "git commit" gives output similar to "git status" when there is + nothing to commit, but without honoring the advise.statusHints + configuration variable, which has been corrected. + + * has_object_file() said "no" given an object registered to the + system via pretend_object_file(), making it inconsistent with + read_object_file(), causing lazy fetch to attempt fetching an + empty tree from promisor remotes. + + * The code that tries to skip over the entries for the paths in a + single directory using the cache-tree was not careful enough + against corrupt index file. + + * Complete an update to tutorial that encourages "git switch" over + "git checkout" that was done only half-way. + + * Reduce unnecessary round-trip when running "ls-remote" over the + stateless RPC mechanism. + + * "git restore --staged" did not correctly update the cache-tree + structure, resulting in bogus trees to be written afterwards, which + has been corrected. + + * The code recently added to move to the entry beyond the ones in the + same directory in the index in the sparse-cone mode did not count + the number of entries to skip over incorrectly, which has been + corrected. + + * Work around test breakages caused by custom regex engine used in + libasan, when address sanitizer is used with more recent versions + of gcc and clang. + + * "git fetch --refmap=" option has got a better documentation. + + * Corner case bugs in "git clean" that stems from a (necessarily for + performance reasons) awkward calling convention in the directory + enumeration API has been corrected. + + * "git grep --no-index" should not get affected by the contents of + the .gitmodules file but when "--recurse-submodules" is given or + the "submodule.recurse" variable is set, it did. Now these + settings are ignored in the "--no-index" mode. + + * Technical details of the bundle format has been documented. + + * Unhelpful warning messages during documentation build have been + squelched. + +Also contains various documentation updates, code clean-ups and minor fixups. diff --git a/Documentation/RelNotes/2.25.2.txt b/Documentation/RelNotes/2.25.2.txt new file mode 100644 index 0000000000..303c53a17f --- /dev/null +++ b/Documentation/RelNotes/2.25.2.txt @@ -0,0 +1,60 @@ +Git 2.25.2 Release Notes +======================== + +Fixes since v2.25.1 +------------------- + + * Minor bugfixes to "git add -i" that has recently been rewritten in C. + + * An earlier update to show the location of working tree in the error + message did not consider the possibility that a git command may be + run in a bare repository, which has been corrected. + + * The "--recurse-submodules" option of various subcommands did not + work well when run in an alternate worktree, which has been + corrected. + + * Running "git rm" on a submodule failed unnecessarily when + .gitmodules is only cache-dirty, which has been corrected. + + * "git rebase -i" identifies existing commits in its todo file with + their abbreviated object name, which could become ambigous as it + goes to create new commits, and has a mechanism to avoid ambiguity + in the main part of its execution. A few other cases however were + not covered by the protection against ambiguity, which has been + corrected. + + * The index-pack code now diagnoses a bad input packstream that + records the same object twice when it is used as delta base; the + code used to declare a software bug when encountering such an + input, but it is an input error. + + * The code to automatically shrink the fan-out in the notes tree had + an off-by-one bug, which has been killed. + + * "git check-ignore" did not work when the given path is explicitly + marked as not ignored with a negative entry in the .gitignore file. + + * The merge-recursive machinery failed to refresh the cache entry for + a merge result in a couple of places, resulting in an unnecessary + merge failure, which has been fixed. + + * Fix for a bug revealed by a recent change to make the protocol v2 + the default. + + * "git merge signed-tag" while lacking the public key started to say + "No signature", which was utterly wrong. This regression has been + reverted. + + * MinGW's poll() emulation has been improved. + + * "git show" and others gave an object name in raw format in its + error output, which has been corrected to give it in hex. + + * Both "git ls-remote -h" and "git grep -h" give short usage help, + like any other Git subcommand, but it is not unreasonable to expect + that the former would behave the same as "git ls-remote --head" + (there is no other sensible behaviour for the latter). The + documentation has been updated in an attempt to clarify this. + +Also contains various documentation updates, code clean-ups and minor fixups. diff --git a/Documentation/RelNotes/2.25.3.txt b/Documentation/RelNotes/2.25.3.txt new file mode 100644 index 0000000000..15f7f21f10 --- /dev/null +++ b/Documentation/RelNotes/2.25.3.txt @@ -0,0 +1,5 @@ +Git v2.25.3 Release Notes +========================= + +This release merges the security fix that appears in v2.17.4; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.25.4.txt b/Documentation/RelNotes/2.25.4.txt new file mode 100644 index 0000000000..0dbb5daeec --- /dev/null +++ b/Documentation/RelNotes/2.25.4.txt @@ -0,0 +1,5 @@ +Git v2.25.4 Release Notes +========================= + +This release merges the security fix that appears in v2.17.5; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.25.5.txt b/Documentation/RelNotes/2.25.5.txt new file mode 100644 index 0000000000..fcb9566b15 --- /dev/null +++ b/Documentation/RelNotes/2.25.5.txt @@ -0,0 +1,7 @@ +Git v2.25.5 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4 and v2.24.4 to address +the security issue CVE-2021-21300; see the release notes for +these versions for details. diff --git a/Documentation/RelNotes/2.26.0.txt b/Documentation/RelNotes/2.26.0.txt new file mode 100644 index 0000000000..3a7a734c26 --- /dev/null +++ b/Documentation/RelNotes/2.26.0.txt @@ -0,0 +1,341 @@ +Git 2.26 Release Notes +====================== + +Updates since v2.25 +------------------- + +Backward compatibility notes + + * "git rebase" uses a different backend that is based on the 'merge' + machinery by default. There are a few known differences in the + behaviour from the traditional machinery based on patch+apply. + + If your workflow is negatively affected by this change, please + report it to git@vger.kernel.org so that we can take a look into + it. After doing so, you can set the 'rebase.backend' configuration + variable to 'apply', in order to use the old default behaviour in + the meantime. + + +UI, Workflows & Features + + * Sample credential helper for using .netrc has been updated to work + out of the box. + + * gpg.minTrustLevel configuration variable has been introduced to + tell various signature verification codepaths the required minimum + trust level. + + * The command line completion (in contrib/) learned to complete + subcommands and arguments to "git worktree". + + * Disambiguation logic to tell revisions and pathspec apart has been + tweaked so that backslash-escaped glob special characters do not + count in the "wildcards are pathspec" rule. + + * One effect of specifying where the GIT_DIR is (either with the + environment variable, or with the "git --git-dir=<where> cmd" + option) is to disable the repository discovery. This has been + placed a bit more stress in the documentation, as new users often + get confused. + + * Two help messages given when "git add" notices the user gave it + nothing to add have been updated to use advise() API. + + * A new version of fsmonitor-watchman hook has been introduced, to + avoid races. + + * "git config" learned to show in which "scope", in addition to in + which file, each config setting comes from. + + * The basic 7 colors learned the brighter counterparts + (e.g. "brightred"). + + * "git sparse-checkout" learned a new "add" subcommand. + + * A configuration element used for credential subsystem can now use + wildcard pattern to specify for which set of URLs the entry + applies. + + * "git clone --recurse-submodules --single-branch" now uses the same + single-branch option when cloning the submodules. + + * "git rm" and "git stash" learns the new "--pathspec-from-file" + option. + + * "git am --show-current-patch" is a way to show the piece of e-mail + for the stopped step, which is not suitable to directly feed "git + apply" (it is designed to be a good "git am" input). It learned a + new option to show only the patch part. + + * Handling of conflicting renames in merge-recursive have further + been made consistent with how existing codepaths try to mimic what + is done to add/add conflicts. + + +Performance, Internal Implementation, Development Support etc. + + * Tell .editorconfig that in this project, *.txt files are indented + with tabs. + + * The test-lint machinery knew to check "VAR=VAL shell_function" + construct, but did not check "VAR= shell_function", which has been + corrected. + + * Replace "git config --bool" calls with "git config --type=bool" in + sample templates. + + * The effort to move "git-add--interactive" to C continues. + + * Improve error message generation for "git submodule add". + + * Preparation of test scripts for the day when the object names will + use SHA-256 continues. + + * Warn programmers about pretend_object_file() that allows the code + to tentatively use in-core objects. + + * The way "git pack-objects" reuses objects stored in existing pack + to generate its result has been improved. + + * The transport protocol version 2 becomes the default one. + + * Traditionally, we avoided threaded grep while searching in objects + (as opposed to files in the working tree) as accesses to the object + layer is not thread-safe. This limitation is getting lifted. + + * "git rebase -i" (and friends) used to unnecessarily check out the + tip of the branch to be rebased, which has been corrected. + + * A low-level API function get_oid(), that accepts various ways to + name an object, used to issue end-user facing error messages + without l10n, which has been updated to be translatable. + + * Unneeded connectivity check is now disabled in a partial clone when + fetching into it. + + * Some rough edges in the sparse-checkout feature, especially around + the cone mode, have been cleaned up. + + * The diff-* plumbing family of subcommands now pay attention to the + diff.wsErrorHighlight configuration, which has been ignored before; + this allows "git add -p" to also show the whitespace problems to + the end user. + + * Some codepaths were given a repository instance as a parameter to + work in the repository, but passed the_repository instance to its + callees, which has been cleaned up (somewhat). + + * Memory footprint and performance of "git name-rev" has been + improved. + + * The object reachability bitmap machinery and the partial cloning + machinery were not prepared to work well together, because some + object-filtering criteria that partial clones use inherently rely + on object traversal, but the bitmap machinery is an optimization + to bypass that object traversal. There however are some cases + where they can work together, and they were taught about them. + + * "git rebase" has learned to use the merge backend (i.e. the + machinery that drives "rebase -i") by default, while allowing + "--apply" option to use the "apply" backend (e.g. the moral + equivalent of "format-patch piped to am"). The rebase.backend + configuration variable can be set to customize. + + * Underlying machinery of "git bisect--helper" is being refactored + into pieces that are more easily reused. + + +Fixes since v2.25 +----------------- + + * "git commit" gives output similar to "git status" when there is + nothing to commit, but without honoring the advise.statusHints + configuration variable, which has been corrected. + + * has_object_file() said "no" given an object registered to the + system via pretend_object_file(), making it inconsistent with + read_object_file(), causing lazy fetch to attempt fetching an + empty tree from promisor remotes. + + * Complete an update to tutorial that encourages "git switch" over + "git checkout" that was done only half-way. + + * C pedantry ;-) fix. + + * The code that tries to skip over the entries for the paths in a + single directory using the cache-tree was not careful enough + against corrupt index file. + + * Reduce unnecessary round-trip when running "ls-remote" over the + stateless RPC mechanism. + + * "git restore --staged" did not correctly update the cache-tree + structure, resulting in bogus trees to be written afterwards, which + has been corrected. + + * The code recently added to move to the entry beyond the ones in the + same directory in the index in the sparse-cone mode did not count + the number of entries to skip over incorrectly, which has been + corrected. + + * Rendering by "git log --graph" of ancestry lines leading to a merge + commit were made suboptimal to waste vertical space a bit with a + recent update, which has been corrected. + + * Work around test breakages caused by custom regex engine used in + libasan, when address sanitizer is used with more recent versions + of gcc and clang. + + * Minor bugfixes to "git add -i" that has recently been rewritten in C. + + * "git fetch --refmap=" option has got a better documentation. + + * "git checkout X" did not correctly fail when X is not a local + branch but could name more than one remote-tracking branches + (i.e. to be dwimmed as the starting point to create a corresponding + local branch), which has been corrected. + (merge fa74180d08 am/checkout-file-and-ref-ref-ambiguity later to maint). + + * Corner case bugs in "git clean" that stems from a (necessarily for + performance reasons) awkward calling convention in the directory + enumeration API has been corrected. + + * A fetch that is told to recursively fetch updates in submodules + inevitably produces reams of output, and it becomes hard to spot + error messages. The command has been taught to enumerate + submodules that had errors at the end of the operation. + (merge 0222540827 es/fetch-show-failed-submodules-atend later to maint). + + * The "--recurse-submodules" option of various subcommands did not + work well when run in an alternate worktree, which has been + corrected. + + * Futureproofing a test not to depend on the current implementation + detail. + + * Running "git rm" on a submodule failed unnecessarily when + .gitmodules is only cache-dirty, which has been corrected. + + * C pedantry ;-) fix. + + * "git grep --no-index" should not get affected by the contents of + the .gitmodules file but when "--recurse-submodules" is given or + the "submodule.recurse" variable is set, it did. Now these + settings are ignored in the "--no-index" mode. + + * Technical details of the bundle format has been documented. + + * Unhelpful warning messages during documentation build have been squelched. + + * "git rebase -i" identifies existing commits in its todo file with + their abbreviated object name, which could become ambiguous as it + goes to create new commits, and has a mechanism to avoid ambiguity + in the main part of its execution. A few other cases however were + not covered by the protection against ambiguity, which has been + corrected. + + * Allow the rebase.missingCommitsCheck configuration to kick in when + "rebase --edit-todo" and "rebase --continue" restarts the procedure. + (merge 5a5445d878 ag/edit-todo-drop-check later to maint). + + * The way "git submodule status" reports an initialized but not yet + populated submodule has not been reimplemented correctly when a + part of the "git submodule" command was rewritten in C, which has + been corrected. + (merge f38c92452d pk/status-of-uncloned-submodule later to maint). + + * The code to automatically shrink the fan-out in the notes tree had + an off-by-one bug, which has been killed. + + * The index-pack code now diagnoses a bad input packstream that + records the same object twice when it is used as delta base; the + code used to declare a software bug when encountering such an + input, but it is an input error. + + + * The code to compute the commit-graph has been taught to use a more + robust way to tell if two object directories refer to the same + thing. + (merge a7df60cac8 tb/commit-graph-object-dir later to maint). + + * "git remote rename X Y" needs to adjust configuration variables + (e.g. branch.<name>.remote) whose value used to be X to Y. + branch.<name>.pushRemote is now also updated. + + * Update to doc-diff. + + * Doc markup fix. + + * "git check-ignore" did not work when the given path is explicitly + marked as not ignored with a negative entry in the .gitignore file. + + * The merge-recursive machinery failed to refresh the cache entry for + a merge result in a couple of places, resulting in an unnecessary + merge failure, which has been fixed. + + * Fix for a bug revealed by a recent change to make the protocol v2 + the default. + + * In rare cases "git worktree add <path>" could think that <path> + was already a registered worktree even when it wasn't and refuse + to add the new worktree. This has been corrected. + (merge bb69b3b009 es/worktree-avoid-duplication-fix later to maint). + + * "git push" should stop from updating a branch that is checked out + when receive.denyCurrentBranch configuration is set, but it failed + to pay attention to checkouts in secondary worktrees. This has + been corrected. + (merge 4d864895a2 hv/receive-denycurrent-everywhere later to maint). + + * "git rebase BASE BRANCH" rebased/updated the tip of BRANCH and + checked it out, even when the BRANCH is checked out in a different + worktree. This has been corrected. + (merge b5cabb4a96 es/do-not-let-rebase-switch-to-protected-branch later to maint). + + * "git describe" in a repository with multiple root commits sometimes + gave up looking for the best tag to describe a given commit with + too early, which has been adjusted. + + * "git merge signed-tag" while lacking the public key started to say + "No signature", which was utterly wrong. This regression has been + reverted. + + * MinGW's poll() emulation has been improved. + + * "git show" and others gave an object name in raw format in its + error output, which has been corrected to give it in hex. + + * "git fetch" over HTTP walker protocol did not show any progress + output. We inherently do not know how much work remains, but still + we can show something not to bore users. + (merge 7655b4119d rs/show-progress-in-dumb-http-fetch later to maint). + + * Both "git ls-remote -h" and "git grep -h" give short usage help, + like any other Git subcommand, but it is not unreasonable to expect + that the former would behave the same as "git ls-remote --head" + (there is no other sensible behaviour for the latter). The + documentation has been updated in an attempt to clarify this. + + * Other code cleanup, docfix, build fix, etc. + (merge d0d0a357a1 am/update-pathspec-f-f-tests later to maint). + (merge f94f7bd00d am/test-pathspec-f-f-error-cases later to maint). + (merge c513a958b6 ss/t6025-modernize later to maint). + (merge b441717256 dl/test-must-fail-fixes later to maint). + (merge d031049da3 mt/sparse-checkout-doc-update later to maint). + (merge 145136a95a jc/skip-prefix later to maint). + (merge 5290d45134 jk/alloc-cleanups later to maint). + (merge 7a9f8ca805 rs/parse-options-concat-dup later to maint). + (merge 517b60564e rs/strbuf-insertstr later to maint). + (merge f696a2b1c8 jk/mailinfo-cleanup later to maint). + (merge de26f02db1 js/test-avoid-pipe later to maint). + (merge a2dc43414c es/doc-mentoring later to maint). + (merge 02bbbe9df9 es/worktree-cleanup later to maint). + (merge 2ce6d075fa rs/micro-cleanups later to maint). + (merge 27f182b3fc rs/blame-typefix-for-fingerprint later to maint). + (merge 3c29e21eb0 ma/test-cleanup later to maint). + (merge 240fc04f81 ag/rebase-remove-redundant-code later to maint). + (merge d68ce906c7 rs/commit-graph-code-simplification later to maint). + (merge a51d9e8f07 rj/t1050-use-test-path-is-file later to maint). + (merge fd0bc17557 kk/complete-diff-color-moved later to maint). + (merge 65bf820d0e en/test-cleanup later to maint). diff --git a/Documentation/RelNotes/2.26.1.txt b/Documentation/RelNotes/2.26.1.txt new file mode 100644 index 0000000000..1b4ecb3fdc --- /dev/null +++ b/Documentation/RelNotes/2.26.1.txt @@ -0,0 +1,5 @@ +Git v2.26.1 Release Notes +========================= + +This release merges the security fix that appears in v2.17.4; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.26.2.txt b/Documentation/RelNotes/2.26.2.txt new file mode 100644 index 0000000000..d434d0c695 --- /dev/null +++ b/Documentation/RelNotes/2.26.2.txt @@ -0,0 +1,5 @@ +Git v2.26.2 Release Notes +========================= + +This release merges the security fix that appears in v2.17.5; see +the release notes for that version for details. diff --git a/Documentation/RelNotes/2.26.3.txt b/Documentation/RelNotes/2.26.3.txt new file mode 100644 index 0000000000..4111c38f0a --- /dev/null +++ b/Documentation/RelNotes/2.26.3.txt @@ -0,0 +1,7 @@ +Git v2.26.3 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4 and v2.25.5 +to address the security issue CVE-2021-21300; see the release +notes for these versions for details. diff --git a/Documentation/RelNotes/2.27.0.txt b/Documentation/RelNotes/2.27.0.txt new file mode 100644 index 0000000000..15518d06c1 --- /dev/null +++ b/Documentation/RelNotes/2.27.0.txt @@ -0,0 +1,525 @@ +Git 2.27 Release Notes +====================== + +Updates since v2.26 +------------------- + +Backward compatibility notes + + * When "git describe C" finds that commit C is pointed by a signed or + annotated tag, which records T as its tagname in the object, the + command gives T as its answer. Even if the user renames or moves + such a tag from its natural location in the "refs/tags/" hierarchy, + "git describe C" would still give T as the answer, but in such a + case "git show T^0" would no longer work as expected. There may be + nothing at "refs/tags/T" or even worse there may be a different tag + instead. + + Starting from this version, "git describe" will always use the + "long" version, as if the "--long" option were given, when giving + its output based on such a misplaced tag to work around the problem. + + * "git pull" issues a warning message until the pull.rebase + configuration variable is explicitly given, which some existing + users may find annoying---those who prefer not to rebase need to + set the variable to false to squelch the warning. + + * The transport protocol version 2, which was promoted to the default + in Git 2.26 release, turned out to have some remaining rough edges, + so it has been demoted from the default. + + +UI, Workflows & Features + + * A handful of options to configure SSL when talking to proxies have + been added. + + * Smudge/clean conversion filters are now given more information + (e.g. the object of the tree-ish in which the blob being converted + appears, in addition to its path, which has already been given). + + * When "git describe C" finds an annotated tag with tagname A to be + the best name to explain commit C, and the tag is stored in a + "wrong" place in the refs/tags hierarchy, e.g. refs/tags/B, the + command gave a warning message but used A (not B) to describe C. + If C is exactly at the tag, the describe output would be "A", but + "git rev-parse A^0" would not be equal as "git rev-parse C^0". The + behavior of the command has been changed to use the "long" form + i.e. A-0-gOBJECTNAME, which is correctly interpreted by rev-parse. + + * "git pull" learned to warn when no pull.rebase configuration + exists, and neither --[no-]rebase nor --ff-only is given (which + would result a merge). + + * "git p4" learned four new hooks and also "--no-verify" option to + bypass them (and the existing "p4-pre-submit" hook). + + * "git pull" shares many options with underlying "git fetch", but + some of them were not documented and some of those that would make + sense to pass down were not passed down. + + * "git rebase" learned the "--no-gpg-sign" option to countermand + commit.gpgSign the user may have. + + * The output from "git format-patch" uses RFC 2047 encoding for + non-ASCII letters on From: and Subject: headers, so that it can + directly be fed to e-mail programs. A new option has been added + to produce these headers in raw. + + * "git log" learned "--show-pulls" that helps pathspec limited + history views; a merge commit that takes the whole change from a + side branch, which is normally omitted from the output, is shown + in addition to the commits that introduce real changes. + + * The interactive input from various codepaths are consolidated and + any prompt possibly issued earlier are fflush()ed before we read. + + * Allow "git rebase" to reapply all local commits, even if the may be + already in the upstream, without checking first. + + * The 'pack.useSparse' configuration variable now defaults to 'true', + enabling an optimization that has been experimental since Git 2.21. + + * "git rebase" happens to call some hooks meant for "checkout" and + "commit" by this was not a designed behaviour than historical + accident. This has been documented. + + * "git merge" learns the "--autostash" option. + + * "sparse-checkout" UI improvements. + + * "git update-ref --stdin" learned a handful of new verbs to let the + user control ref update transactions more explicitly, which helps + as an ingredient to implement two-phase commit-style atomic + ref-updates across multiple repositories. + + * "git commit-graph write" learned different ways to write out split + files. + + * Introduce an extension to the commit-graph to make it efficient to + check for the paths that were modified at each commit using Bloom + filters. + + * The approxidate parser learns to parse seconds with fraction and + ignore fractional part. + + * The userdiff patterns for Markdown documents have been added. + + * The sparse-checkout patterns have been forbidden from excluding all + paths, leaving an empty working tree, for a long time. This + limitation has been lifted. + + * "git restore --staged --worktree" now defaults to take the contents + out of "HEAD", instead of erring out. + + * "git p4" learned to recover from a (broken) state where a directory + and a file are recorded at the same path in the Perforce repository + the same way as their clients do. + + * "git multi-pack-index repack" has been taught to honor some + repack.* configuration variables. + + +Performance, Internal Implementation, Development Support etc. + + * The advise API has been revamped to allow more systematic enumeration of + advice knobs in the future. + + * SHA-256 transition continues. + + * The code to interface with GnuPG has been refactored. + + * "git stash" has kept an escape hatch to use the scripted version + for a few releases, which got stale. It has been removed. + + * Enable tests that require GnuPG on Windows. + + * Minor test usability improvement. + + * Trace2 enhancement to allow logging of the environment variables. + + * Test clean-up continues. + + * Perf-test update. + + * A Windows-specific test element has been made more robust against + misuse from both user's environment and programmer's errors. + + * Various tests have been updated to work around issues found with + shell utilities that come with busybox etc. + + * The config API made mixed uses of int and size_t types to represent + length of various pieces of text it parsed, which has been updated + to use the correct type (i.e. size_t) throughout. + + * The "--decorate-refs" and "--decorate-refs-exclude" options "git + log" takes have learned a companion configuration variable + log.excludeDecoration that sits at the lowest priority in the + family. + + * A new CI job to build and run test suite on linux with musl libc + has been added. + + * Update the CI configuration to use GitHub Actions, retiring the one + based on Azure Pipelines. + + * The directory traversal code had redundant recursive calls which + made its performance characteristics exponential with respect to + the depth of the tree, which was corrected. + + * "git blame" learns to take advantage of the "changed-paths" Bloom + filter stored in the commit-graph file. + + * The "bugreport" tool has been added. + + * The object walk with object filter "--filter=tree:0" can now take + advantage of the pack bitmap when available. + + * Instead of always building all branches at GitHub via Actions, + users can specify which branches to build. + + * Codepaths that show progress meter have been taught to also use the + start_progress() and the stop_progress() calls as a "region" to be + traced. + + * Instead of downloading Windows SDK for CI jobs for windows builds + from an external site (wingit.blob.core.windows.net), use the one + created in the windows-build job, to work around quota issues at + the external site. + + +Fixes since v2.26 +----------------- + + * The real_path() convenience function can easily be misused; with a + bit of code refactoring in the callers' side, its use has been + eliminated. + (merge 49d3c4b481 am/real-path-fix later to maint). + + * Update "git p4" to work with Python 3. + (merge 6bb40ed20a yz/p4-py3 later to maint). + + * The mechanism to prevent "git commit" from making an empty commit + or amending during an interrupted cherry-pick was broken during the + rewrite of "git rebase" in C, which has been corrected. + (merge 430b75f720 pw/advise-rebase-skip later to maint). + + * Fix "git checkout --recurse-submodules" of a nested submodule + hierarchy. + (merge 846f34d351 pb/recurse-submodules-fix later to maint). + + * The "--fork-point" mode of "git rebase" regressed when the command + was rewritten in C back in 2.20 era, which has been corrected. + (merge f08132f889 at/rebase-fork-point-regression-fix later to maint). + + * The import-tars importer (in contrib/fast-import/) used to create + phony files at the top-level of the repository when the archive + contains global PAX headers, which made its own logic to detect and + omit the common leading directory ineffective, which has been + corrected. + (merge c839fcff65 js/import-tars-do-not-make-phony-files-from-pax-headers later to maint). + + * Simplify the commit ancestry connectedness check in a partial clone + repository in which "promised" objects are assumed to be obtainable + lazily on-demand from promisor remote repositories. + (merge 2b98478c6f jt/connectivity-check-optim-in-partial-clone later to maint). + + * The server-end of the v2 protocol to serve "git clone" and "git + fetch" was not prepared to see a delim packets at unexpected + places, which led to a crash. + (merge cacae4329f jk/harden-protocol-v2-delim-handling later to maint). + + * When fed a midx that records no objects, some codepaths tried to + loop from 0 through (num_objects-1), which, due to integer + arithmetic wrapping around, made it nonsense operation with out of + bounds array accesses. The code has been corrected to reject such + an midx file. + (merge 796d61cdc0 dr/midx-avoid-int-underflow later to maint). + + * Utitiles run via the run_command() API were not spawned correctly + on Cygwin, when the paths to them are given as a full path with + backslashes. + (merge 05ac8582bc ak/run-command-on-cygwin-fix later to maint). + + * "git pull --rebase" tried to run a rebase even after noticing that + the pull results in a fast-forward and no rebase is needed nor + sensible, for the past few years due to a mistake nobody noticed. + (merge fbae70ddc6 en/pull-do-not-rebase-after-fast-forwarding later to maint). + + * "git rebase" with the merge backend did not work well when the + rebase.abbreviateCommands configuration was set. + (merge de9f1d3ef4 ag/rebase-merge-allow-ff-under-abbrev-command later to maint). + + * The logic to auto-follow tags by "git clone --single-branch" was + not careful to avoid lazy-fetching unnecessary tags, which has been + corrected. + (merge 167a575e2d jk/use-quick-lookup-in-clone-for-tag-following later to maint). + + * "git rebase -i" did not leave the reflog entries correctly. + (merge 1f6965f994 en/sequencer-reflog-action later to maint). + + * The more aggressive updates to remote-tracking branches we had for + the past 7 years or so were not reflected in the documentation, + which has been corrected. + (merge a44088435c pb/pull-fetch-doc later to maint). + + * We've left the command line parsing of "git log :/a/b/" broken for + about a full year without anybody noticing, which has been + corrected. + (merge 0220461071 jc/missing-ref-store-fix later to maint). + + * Misc fixes for Windows. + (merge 3efc128cd5 js/mingw-fixes later to maint). + + * "git rebase" (again) learns to honor "--no-keep-empty", which lets + the user to discard commits that are empty from the beginning (as + opposed to the ones that become empty because of rebasing). The + interactive rebase also marks commits that are empty in the todo. + (merge 50ed76148a en/rebase-no-keep-empty later to maint). + + * Parsing the host part out of URL for the credential helper has been corrected. + (merge 4c5971e18a jk/credential-parsing-end-of-host-in-URL later to maint). + + * Document the recommended way to abort a failing test early (e.g. by + exiting a loop), which is to say "return 1". + (merge 7cc112dc95 jc/doc-test-leaving-early later to maint). + + * The code that refreshes the last access and modified time of + on-disk packfiles and loose object files have been updated. + (merge 312cd76130 lr/freshen-file-fix later to maint). + + * Validation of push certificate has been made more robust against + timing attacks. + (merge 719483e547 bc/constant-memequal later to maint). + + * The custom hash function used by "git fast-import" has been + replaced with the one from hashmap.c, which gave us a nice + performance boost. + (merge d8410a816b jk/fast-import-use-hashmap later to maint). + + * The "git submodule" command did not initialize a few variables it + internally uses and was affected by variable settings leaked from + the environment. + (merge 65d100c4dd lx/submodule-clear-variables later to maint). + + * Raise the minimum required version of docbook-xsl package to 1.74, + as 1.74.0 was from late 2008, which is more than 10 years old, and + drop compatibility cruft from our documentation suite. + (merge 3c255ad660 ma/doc-discard-docbook-xsl-1.73 later to maint). + + * "git log" learns "--[no-]mailmap" as a synonym to "--[no-]use-mailmap" + (merge 88acccda38 jc/log-no-mailmap later to maint). + + * "git commit-graph write --expire-time=<timestamp>" did not use the + given timestamp correctly, which has been corrected. + (merge b09b785c78 ds/commit-graph-expiry-fix later to maint). + + * Tests update to use "test-chmtime" instead of "touch -t". + (merge e892a56845 ds/t5319-touch-fix later to maint). + + * "git diff" in a partial clone learned to avoid lazy loading blob + objects in more casese when they are not needed. + (merge 95acf11a3d jt/avoid-prefetch-when-able-in-diff later to maint). + + * "git push --atomic" used to show failures for refs that weren't + even pushed, which has been corrected. + (merge dfe1b7f19c jx/atomic-push later to maint). + + * Code in builtin/*, i.e. those can only be called from within + built-in subcommands, that implements bulk of a couple of + subcommands have been moved to libgit.a so that they could be used + by others. + (merge 9460fd48b5 dl/libify-a-few later to maint). + + * Allowing the user to split a patch hunk while "git stash -p" does + not work well; a band-aid has been added to make this (partially) + work better. + + * "git diff-tree --pretty --notes" used to hit an assertion failure, + as it forgot to initialize the notes subsystem. + (merge 5778b22b3d tb/diff-tree-with-notes later to maint). + + * "git range-diff" fixes. + (merge 8d1675eb7f vd/range-diff-with-custom-pretty-format-fix later to maint). + + * "git grep" did not quote a path with unusual character like other + commands (like "git diff", "git status") do, but did quote when run + from a subdirectory, both of which has been corrected. + (merge 45115d8490 mt/grep-cquote-path later to maint). + + * GNU/Hurd is also among the ones that need the fopen() wrapper. + (merge 274a1328fb jc/gnu-hurd-lets-fread-read-dirs later to maint). + + * Those fetching over protocol v2 from linux-next and other kernel + repositories are reporting that v2 often fetches way too much than + needed. + (merge 11c7f2a30b jn/demote-proto2-from-default later to maint). + + * The upload-pack protocol v2 gave up too early before finding a + common ancestor, resulting in a wasteful fetch from a fork of a + project. This has been corrected to match the behaviour of v0 + protocol. + (merge 2f0a093dd6 jt/v2-fetch-nego-fix later to maint). + + * The build procedure did not use the libcurl library and its include + files correctly for a custom-built installation. + (merge 0573831950 jk/build-with-right-curl later to maint). + + * Tighten "git mailinfo" to notice and error out when decoded result + contains NUL in it. + (merge 3919997447 dd/mailinfo-with-nul later to maint). + + * Fix in-core inconsistency after fetching into a shallow repository + that broke the code to write out commit-graph. + (merge 37b9dcabfc tb/reset-shallow later to maint). + + * The commit-graph code exhausted file descriptors easily when it + does not have to. + (merge c8828530b7 tb/commit-graph-fd-exhaustion-fix later to maint). + + * The multi-pack-index left mmapped file descriptors open when it + does not have to. + (merge 6c7ff7cf7f ds/multi-pack-index later to maint). + + * Recent update to Homebrew used by macOS folks breaks build by + moving gettext library and necessary headers. + (merge a0b3108618 ds/build-homebrew-gettext-fix later to maint). + + * Incompatible options "--root" and "--fork-point" of "git rebase" + have been marked and documented as being incompatible. + (merge a35413c378 en/rebase-root-and-fork-point-are-incompatible later to maint). + + * Error and verbose trace messages from "git push" did not redact + credential material embedded in URLs. + (merge d192fa5006 js/anonymise-push-url-in-errors later to maint). + + * Update the parser used for credential.<URL>.<variable> + configuration, to handle <URL>s with '/' in them correctly. + (merge b44d0118ac bc/wildcard-credential later to maint). + + * Recent updates broke parsing of "credential.<url>.<key>" where + <url> is not a full URL (e.g. [credential "https://"] helper = ...) + stopped working, which has been corrected. + (merge 9a121b0d22 js/partial-urlmatch-2.17 later to maint). + (merge cd93e6c029 js/partial-urlmatch later to maint). + + * Some of the files commit-graph subsystem keeps on disk did not + correctly honor the core.sharedRepository settings and some were + left read-write. + + * In error messages that "git switch" mentions its option to create a + new branch, "-b/-B" options were shown, where "-c/-C" options + should be, which has been corrected. + (merge 7c16ef7577 dl/switch-c-option-in-error-message later to maint). + + * With the recent tightening of the code that is used to parse + various parts of a URL for use in the credential subsystem, a + hand-edited credential-store file causes the credential helper to + die, which is a bit too harsh to the users. Demote the error + behaviour to just ignore and keep using well-formed lines instead. + (merge c03859a665 cb/credential-store-ignore-bogus-lines later to maint). + + * The samples in the credential documentation has been updated to + make it clear that we depict what would appear in the .git/config + file, by adding appropriate quotes as needed.. + (merge 177681a07e jk/credential-sample-update later to maint). + + * "git branch" and other "for-each-ref" variants accepted multiple + --sort=<key> options in the increasing order of precedence, but it + had a few breakages around "--ignore-case" handling, and tie-breaking + with the refname, which have been fixed. + (merge 7c5045fc18 jk/for-each-ref-multi-key-sort-fix later to maint). + + * The coding guideline for shell scripts instructed to refer to a + variable with dollar-sign inside arithmetic expansion to work + around a bug in old versions of dash, which is a thing of the past. + Now we are not forbidden from writing $((var+1)). + (merge 32b5fe7f0e jk/arith-expansion-coding-guidelines later to maint). + + * The <stdlib.h> header on NetBSD brings in its own definition of + hmac() function (eek), which conflicts with our own and unrelated + function with the same name. Our function has been renamed to work + around the issue. + (merge 3013118eb8 cb/avoid-colliding-with-netbsd-hmac later to maint). + + * The basic test did not honor $TEST_SHELL_PATH setting, which has + been corrected. + (merge 0555e4af58 cb/t0000-use-the-configured-shell later to maint). + + * Minor in-code comments and documentation updates around credential + API. + (merge 1aed817f99 cb/credential-doc-fixes later to maint). + + * Teach "am", "commit", "merge" and "rebase", when they are run with + the "--quiet" option, to pass "--quiet" down to "gc --auto". + (merge 7c3e9e8cfb jc/auto-gc-quiet later to maint). + + * The code to skip unmerged paths in the index when sparse checkout + is in use would have made out-of-bound access of the in-core index + when the last path was unmerged, which has been corrected. + + * Serving a "git fetch" client over "git://" and "ssh://" protocols + using the on-wire protocol version 2 was buggy on the server end + when the client needs to make a follow-up request to + e.g. auto-follow tags. + (merge 08450ef791 cc/upload-pack-v2-fetch-fix later to maint). + + * "git bisect replay" had trouble with input files when they used + CRLF line ending, which has been corrected. + (merge 6c722cbe5a cw/bisect-replay-with-dos later to maint). + + * "rebase -i" segfaulted when rearranging a sequence that has a + fix-up that applies another fix-up (which may or may not be a + fix-up of yet another step). + (merge 02471e7e20 js/rebase-autosquash-double-fixup-fix later to maint). + + * "git fsck" ensures that the paths recorded in tree objects are + sorted and without duplicates, but it failed to notice a case where + a blob is followed by entries that sort before a tree with the same + name. This has been corrected. + (merge 9068cfb20f rs/fsck-duplicate-names-in-trees later to maint). + + * Code clean-up by removing a compatibility implementation of a + function we no longer use. + (merge 84b0115f0d cb/no-more-gmtime later to maint). + + * When a binary file gets modified and renamed on both sides of history + to different locations, both files would be written to the working + tree but both would have the contents from "ours". This has been + corrected so that the path from each side gets their original content. + + * Fix for a copy-and-paste error introduced during 2.20 era. + (merge e68a5272b1 ds/multi-pack-verify later to maint). + + * Update an unconditional use of "grep -a" with a perl script in a test. + (merge 1eb7371236 dd/t5703-grep-a-fix later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 564956f358 jc/maintain-doc later to maint). + (merge 7422b2a0a1 sg/commit-slab-clarify-peek later to maint). + (merge 9c688735f6 rs/doc-passthru-fetch-options later to maint). + (merge 757c2ba3e2 en/oidset-uninclude-hashmap later to maint). + (merge 8312aa7d74 jc/config-tar later to maint). + (merge d00a5bdd50 ss/submodule-foreach-cb later to maint). + (merge 64d1022e14 ar/test-style-fixes later to maint). + (merge 4a465443a6 ds/doc-clone-filter later to maint). + (merge bb2dbe301b jk/t3419-drop-expensive-tests later to maint). + (merge d3507cc712 js/test-junit-finalization-fix later to maint). + (merge 2149b6748f bc/faq later to maint). + (merge 12dc0879f1 jk/test-cleanup later to maint). + (merge 344420bf0f pb/rebase-doc-typofix later to maint). + (merge 7cd54d37dc dl/wrapper-fix-indentation later to maint). + (merge 78725ebda9 jc/allow-strlen-substitution-in-shell-scripts later to maint). + (merge 2ecfcdecc6 jm/gitweb-fastcgi-utf8 later to maint). + (merge 0740d0a5d3 jk/oid-array-cleanups later to maint). + (merge a1aba0c95c js/t0007-typofix later to maint). + (merge 76ba7fa225 ma/config-doc-fix later to maint). + (merge 826f0c0df2 js/subtree-doc-update-to-asciidoctor-2 later to maint). + (merge 88eaf361e0 eb/mboxrd-doc later to maint). + (merge 051cc54941 tm/zsh-complete-switch-restore later to maint). + (merge 39102cf4fe ms/doc-revision-illustration-fix later to maint). + (merge 4d9378bfad eb/gitweb-more-trailers later to maint). + (merge bdccbf7047 mt/doc-worktree-ref later to maint). + (merge ce9baf234f dl/push-recurse-submodules-fix later to maint). + (merge 4153274052 bc/doc-credential-helper-value later to maint). + (merge 5c7bb0146e jc/codingstyle-compare-with-null later to maint). diff --git a/Documentation/RelNotes/2.27.1.txt b/Documentation/RelNotes/2.27.1.txt new file mode 100644 index 0000000000..a1e08a9f72 --- /dev/null +++ b/Documentation/RelNotes/2.27.1.txt @@ -0,0 +1,7 @@ +Git v2.27.1 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, v2.25.5 +and v2.26.3 to address the security issue CVE-2021-21300; see +the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.28.0.txt b/Documentation/RelNotes/2.28.0.txt new file mode 100644 index 0000000000..6baf781380 --- /dev/null +++ b/Documentation/RelNotes/2.28.0.txt @@ -0,0 +1,236 @@ +Git 2.28 Release Notes +====================== + +Updates since v2.27 +------------------- + +Backward compatibility notes + + * "fetch.writeCommitGraph" is deemed to be still a bit too risky and + is no longer part of the "feature.experimental" set. + + +UI, Workflows & Features + + * The commands in the "diff" family learned to honor "diff.relative" + configuration variable. + + * The check in "git fsck" to ensure that the tree objects are sorted + still had corner cases it missed unsorted entries. + + * The interface to redact sensitive information in the trace output + has been simplified. + + * The command line completion (in contrib/) learned to complete + options that the "git switch" command takes. + + * "git diff" used to take arguments in random and nonsense range + notation, e.g. "git diff A..B C", "git diff A..B C...D", etc., + which has been cleaned up. + + * "git diff-files" has been taught to say paths that are marked as + intent-to-add are new files, not modified from an empty blob. + + * "git status" learned to report the status of sparse checkout. + + * "git difftool" has trouble dealing with paths added to the index + with the intent-to-add bit. + + * "git fast-export --anonymize" learned to take customized mapping to + allow its users to tweak its output more usable for debugging. + + * The command line completion support (in contrib/) used to be + prepared to work with "set -u" but recent changes got a bit more + sloppy. This has been corrected. + + * "git gui" now allows opening work trees from the start-up dialog. + + +Performance, Internal Implementation, Development Support etc. + + * Code optimization for a common case. + (merge 8777616e4d an/merge-single-strategy-optim later to maint). + + * We've adopted a convention that any on-stack structure can be + initialized to have zero values in all fields with "= { 0 }", + even when the first field happens to be a pointer, but sparse + complained that a null pointer should be spelled NULL for a long + time. Start using -Wno-universal-initializer option to squelch + it (the latest sparse has it on by default). + + * "git log -L..." now takes advantage of the "which paths are touched + by this commit?" info stored in the commit-graph system. + + * As FreeBSD is not the only platform whose regexp library reports + a REG_ILLSEQ error when fed invalid UTF-8, add logic to detect that + automatically and skip the affected tests. + + * "git bugreport" learns to report what shell is in use. + + * Support for GIT_CURL_VERBOSE has been rewritten in terms of + GIT_TRACE_CURL. + + * Preliminary clean-ups around refs API, plus file format + specification documentation for the reftable backend. + + * Workaround breakage in MSVC build, where "curl-config --cflags" + gives settings appropriate for GCC build. + + * Code clean-up of "git clean" resulted in a fix of recent + performance regression. + + * Code clean-up in the codepath that serves "git fetch" continues. + + * "git merge-base --is-ancestor" is taught to take advantage of the + commit graph. + + * Rewrite of parts of the scripted "git submodule" Porcelain command + continues; this time it is "git submodule set-branch" subcommand's + turn. + + * The "fetch/clone" protocol has been updated to allow the server to + instruct the clients to grab pre-packaged packfile(s) in addition + to the packed object data coming over the wire. + + * A misdesigned strbuf_write_fd() function has been retired. + + * SHA-256 migration work continues, including CVS/SVN interface. + + * A few fields in "struct commit" that do not have to always be + present have been moved to commit slabs. + + * API cleanup for get_worktrees() + + * By renumbering object flag bits, "struct object" managed to lose + bloated inter-field padding. + + * The name of the primary branch in existing repositories, and the + default name used for the first branch in newly created + repositories, is made configurable, so that we can eventually wean + ourselves off of the hardcoded 'master'. + + * The effort to avoid using test_must_fail on non-git command continues. + + * In 2.28-rc0, we corrected a bug that some repository extensions are + honored by mistake even in a version 0 repositories (these + configuration variables in extensions.* namespace were supposed to + have special meaning in repositories whose version numbers are 1 or + higher), but this was a bit too big a change. The behaviour in + recent versions of Git where certain extensions.* were honored by + mistake even in version 0 repositories has been restored. + + +Fixes since v2.27 +----------------- + + * The "--prepare-p4-only" option of "git p4" is supposed to stop + after replaying one changeset, but kept going (by mistake?) + + * The error message from "git checkout -b foo -t bar baz" was + confusing. + + * Some repositories in the wild have commits that record nonsense + committer timezone (e.g. rails.git); "git fast-import" learned an + option to pass these nonsense timestamps intact to allow recreating + existing repositories as-is. + (merge d42a2fb72f en/fast-import-looser-date later to maint). + + * The command line completion script (in contrib/) tried to complete + "git stash -p" as if it were "git stash push -p", but it was too + aggressive and also affected "git stash show -p", which has been + corrected. + (merge fffd0cf520 vs/complete-stash-show-p-fix later to maint). + + * On-the-wire protocol v2 easily falls into a deadlock between the + remote-curl helper and the fetch-pack process when the server side + prematurely throws an error and disconnects. The communication has + been updated to make it more robust. + + * "git checkout -p" did not handle a newly added path at all. + (merge 2c8bd8471a js/checkout-p-new-file later to maint). + + * The code to parse "git bisect start" command line was lax in + validating the arguments. + (merge 4d9005ff5d cb/bisect-helper-parser-fix later to maint). + + * Reduce memory usage during "diff --quiet" in a worktree with too + many stat-unmatched paths. + (merge d2d7fbe129 jk/diff-memuse-optim-with-stat-unmatch later to maint). + + * The reflog entries for "git clone" and "git fetch" did not + anonymize the URL they operated on. + (merge 46da295a77 js/reflog-anonymize-for-clone-and-fetch later to maint). + + * The behaviour of "sparse-checkout" in the state "git clone + --no-checkout" left was changed accidentally in 2.27, which has + been corrected. + + * Use of negative pathspec, while collecting paths including + untracked ones in the working tree, was broken. + + * The same worktree directory must be registered only once, but + "git worktree move" allowed this invariant to be violated, which + has been corrected. + (merge 810382ed37 es/worktree-duplicate-paths later to maint). + + * The effect of sparse checkout settings on submodules is documented. + (merge e7d7c73249 en/sparse-with-submodule-doc later to maint). + + * Code clean-up around "git branch" with a minor bugfix. + (merge dc44639904 dl/branch-cleanup later to maint). + + * A branch name used in a test has been clarified to match what is + going on. + (merge 08dc26061f pb/t4014-unslave later to maint). + + * An in-code comment in "git diff" has been updated. + (merge c592fd4c83 dl/diff-usage-comment-update later to maint). + + * The documentation and some tests have been adjusted for the recent + renaming of "pu" branch to "seen". + (merge 6dca5dbf93 js/pu-to-seen later to maint). + + * The code to push changes over "dumb" HTTP had a bad interaction + with the commit reachability code due to incorrect allocation of + object flag bits, which has been corrected. + (merge 64472d15e9 bc/http-push-flagsfix later to maint). + + * "git send-email --in-reply-to=<msg>" did not use the In-Reply-To: + header with the value given from the command line, and let it be + overridden by the value on In-Reply-To: header in the messages + being sent out (if exists). + (merge f9f60d7066 ra/send-email-in-reply-to-from-command-line-wins later to maint). + + * "git log -Lx,y:path --before=date" lost track of where the range + should be because it didn't take the changes made by the youngest + commits that are omitted from the output into account. + + * When "fetch.writeCommitGraph" configuration is set in a shallow + repository and a fetch moves the shallow boundary, we wrote out + broken commit-graph files that do not match the reality, which has + been corrected. + + * "git checkout" failed to catch an error from fstat() after updating + a path in the working tree. + (merge 35e6e212fd mt/entry-fstat-fallback-fix later to maint). + + * When an aliased command, whose output is piped to a pager by git, + gets killed by a signal, the pager got into a funny state, which + has been corrected (again). + (merge c0d73a59c9 ta/wait-on-aliased-commands-upon-signal later to maint). + + * The code to produce progress output from "git commit-graph --write" + had a few breakages, which have been fixed. + + * Other code cleanup, docfix, build fix, etc. + (merge 2c31a7aa44 jx/pkt-line-doc-count-fix later to maint). + (merge d63ae31962 cb/t5608-cleanup later to maint). + (merge 788db145c7 dl/t-readme-spell-git-correctly later to maint). + (merge 45a87a83bb dl/python-2.7-is-the-floor-version later to maint). + (merge b75a219904 es/advertise-contribution-doc later to maint). + (merge 0c9a4f638a rs/pull-leakfix later to maint). + (merge d546fe2874 rs/commit-reach-leakfix later to maint). + (merge 087bf5409c mk/pb-pretty-email-without-domain-part-fix later to maint). + (merge 5f4ee57ad9 es/worktree-code-cleanup later to maint). + (merge 0172f7834a cc/cat-file-usage-update later to maint). + (merge 81de0c01cf ma/rebase-doc-typofix later to maint). diff --git a/Documentation/RelNotes/2.28.1.txt b/Documentation/RelNotes/2.28.1.txt new file mode 100644 index 0000000000..8484c8297c --- /dev/null +++ b/Documentation/RelNotes/2.28.1.txt @@ -0,0 +1,7 @@ +Git v2.28.1 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, v2.25.5, +v2.26.3 and v2.27.1 to address the security issue CVE-2021-21300; +see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.29.0.txt b/Documentation/RelNotes/2.29.0.txt new file mode 100644 index 0000000000..1f41302ebb --- /dev/null +++ b/Documentation/RelNotes/2.29.0.txt @@ -0,0 +1,514 @@ +Git 2.29 Release Notes +====================== + +Updates since v2.28 +------------------- + +UI, Workflows & Features + + * "git help log" has been enhanced by sharing more material from the + documentation for the underlying "git rev-list" command. + + * "git for-each-ref --format=<>" learned %(contents:size). + + * "git merge" learned to selectively omit " into <branch>" at the end + of the title of default merge message with merge.suppressDest + configuration. + + * The component to respond to "git fetch" request is made more + configurable to selectively allow or reject object filtering + specification used for partial cloning. + + * Stop when "sendmail.*" configuration variables are defined, which + could be a mistaken attempt to define "sendemail.*" variables. + + * The existing backends for "git mergetool" based on variants of vim + have been refactored and then support for "nvim" has been added. + + * "git bisect" learns the "--first-parent" option to find the first + breakage along the first-parent chain. + + * "git log --first-parent -p" showed patches only for single-parent + commits on the first-parent chain; the "--first-parent" option has + been made to imply "-m". Use "--no-diff-merges" to restore the + previous behaviour to omit patches for merge commits. + + * The commit labels used to explain each side of conflicted hunks + placed by the sequencer machinery have been made more readable by + humans. + + * The "--batch-size" option of "git multi-pack-index repack" command + is now used to specify that very small packfiles are collected into + one until the total size roughly exceeds it. + + * The recent addition of SHA-256 support is marked as experimental in + the documentation. + + * "git fetch" learned --no-write-fetch-head option to avoid writing + the FETCH_HEAD file. + + * Command line completion (in contrib/) usually omits redundant, + deprecated and/or dangerous options from its output; it learned to + optionally include all of them. + + * The output from the "diff" family of the commands had abbreviated + object names of blobs involved in the patch, but its length was not + affected by the --abbrev option. Now it is. + + * "git worktree" gained a "repair" subcommand to help users recover + after moving the worktrees or repository manually without telling + Git. Also, "git init --separate-git-dir" no longer corrupts + administrative data related to linked worktrees. + + * The "--format=" option to the "for-each-ref" command and friends + learned a few more tricks, e.g. the ":short" suffix that applies to + "objectname" now also can be used for "parent", "tree", etc. + + * "git worktree add" learns that the "-d" is a synonym to "--detach" + option to create a new worktree without being on a branch. + + * "format-patch --range-diff=<prev> <origin>..HEAD" has been taught + not to ignore <origin> when <prev> is a single version. + + * "add -p" now allows editing paths that were only added in intent. + + * The 'meld' backend of the "git mergetool" learned to give the + underlying 'meld' the '--auto-merge' option, which would help + reduce the amount of text that requires manual merging. + + * "git for-each-ref" and friends that list refs used to allow only + one --merged or --no-merged to filter them; they learned to take + combination of both kind of filtering. + + * "git maintenance", a "git gc"'s big brother, has been introduced to + take care of more repository maintenance tasks, not limited to the + object database cleaning. + + * "git receive-pack" that accepts requests by "git push" learned to + outsource most of the ref updates to the new "proc-receive" hook. + + * "git push" that wants to be atomic and wants to send push + certificate learned not to prepare and sign the push certificate + when it fails the local check (hence due to atomicity it is known + that no certificate is needed). + + * "git commit-graph write" learned to limit the number of bloom + filters that are computed from scratch with the --max-new-filters + option. + + * The transport protocol v2 has become the default again. + + * The installation procedure learned to optionally omit "git-foo" + executable files for each 'foo' built-in subcommand, which are only + required by old timers that still rely on the age old promise that + prepending "git --exec-path" output to PATH early in their script + will keep the "git-foo" calls they wrote working. + + * The command line completion (in contrib/) learned that "git restore + -s <TAB>" is often followed by a refname. + + * "git shortlog" has been taught to group commits by the contents of + the trailer lines, like "Reviewed-by:", "Coauthored-by:", etc. + + * "git archive" learns the "--add-file" option to include untracked + files into a snapshot from a tree-ish. + + * "git fetch" and "git push" support negative refspecs. + + * "git format-patch" learns to take "whenAble" as a possible value + for the format.useAutoBase configuration variable to become no-op + when the automatically computed base does not make sense. + + * Credential helpers are now allowed to terminate lines with CRLF + line ending, as well as LF line ending. + + +Performance, Internal Implementation, Development Support etc. + + * The changed-path Bloom filter is improved using ideas from an + independent implementation. + + * Updates to the changed-paths bloom filter. + + * The test framework has been updated so that most tests will run + with predictable (artificial) timestamps. + + * Preliminary clean-up of the refs API in preparation for adding a + new refs backend "reftable". + + * Dev support to limit the use of test_must_fail to only git commands. + + * While packing many objects in a repository with a promissor remote, + lazily fetching missing objects from the promissor remote one by + one may be inefficient---the code now attempts to fetch all the + missing objects in batch (obviously this won't work for a lazy + clone that lazily fetches tree objects as you cannot even enumerate + what blobs are missing until you learn which trees are missing). + + * The pretend-object mechanism checks if the given object already + exists in the object store before deciding to keep the data + in-core, but the check would have triggered lazy fetching of such + an object from a promissor remote. + + * The argv_array API is useful for not just managing argv but any + "vector" (NULL-terminated array) of strings, and has seen adoption + to a certain degree. It has been renamed to "strvec" to reduce the + barrier to adoption. + + * The final leg of SHA-256 transition plus doc updates. Note that + there is no interoperability between SHA-1 and SHA-256 + repositories yet. + + * CMake support to build with MSVC for Windows bypassing the Makefile. + + * A new helper function has_object() has been introduced to make it + easier to mark object existence checks that do and don't want to + trigger lazy fetches, and a few such checks are converted using it. + + * A no-op replacement function implemented as a C preprocessor macro + does not perform as good a job as one implemented as a "static + inline" function in catching errors in parameters; replace the + former with the latter in <git-compat-util.h> header. + + * Test framework update. + (merge d572f52a64 es/test-cmp-typocatcher later to maint). + + * Updates to "git merge" tests, in preparation for a new merge + strategy backend. + + * midx and commit-graph files now use the byte defined in their file + format specification for identifying the hash function used for + object names. + + * The FETCH_HEAD is now always read from the filesystem regardless of + the ref backend in use, as its format is much richer than the + normal refs, and written directly by "git fetch" as a plain file.. + + * An unused binary has been discarded, and a bunch of commands + have been turned into built-in. + + * A handful of places in in-tree code still relied on being able to + execute the git subcommands, especially built-ins, in "git-foo" + form, which have been corrected. + + * When a packfile is removed by "git repack", multi-pack-index gets + cleared; the code was taught to do so less aggressively by first + checking if the midx actually refers to a pack that no longer + exists. + + * Internal API clean-up to handle two options "diff-index" and "log" + have, which happen to share the same short form, more sensibly. + + * The "add -i/-p" machinery has been written in C but it is not used + by default yet. It is made default to those who are participating + in feature.experimental experiment. + + * Allow maintainers to tweak $(TAR) invocations done while making + distribution tarballs. + + * "git index-pack" learned to resolve deltified objects with greater + parallelism. + + * "diff-highlight" (in contrib/) had a logic to flush its output upon + seeing a blank line but the way it detected a blank line was broken. + + * The logic to skip testing on the tagged commit and the tag itself + was not quite consistent which led to failure of Windows test + tasks. It has been revamped to consistently skip revisions that + have already been tested, based on the tree object of the revision. + + +Fixes since v2.28 +----------------- + + * The "mediawiki" remote backend which lives in contrib/mw-to-git/ + and is not built with git by default, had an RCE bug allowing a + malicious MediaWiki server operator to inject arbitrary commands + for execution by a cloning client. This has been fixed. + + The bug was discovered and reported by Joern Schneeweisz of GitLab + to the git-security mailing list. Its practical impact due to the + obscurity of git-remote-mediawiki was deemed small enough to forgo + a dedicated security release. + + * "git clone --separate-git-dir=$elsewhere" used to stomp on the + contents of the existing directory $elsewhere, which has been + taught to fail when $elsewhere is not an empty directory. + (merge dfaa209a79 bw/fail-cloning-into-non-empty later to maint). + + * With the base fix to 2.27 regresion, any new extensions in a v0 + repository would still be silently honored, which is not quite + right. Instead, complain and die loudly. + (merge ec91ffca04 jk/reject-newer-extensions-in-v0 later to maint). + + * Fetching from a lazily cloned repository resulted at the server + side in attempts to lazy fetch objects that the client side has, + many of which will not be available from the third-party anyway. + (merge 77aa0941ce jt/avoid-lazy-fetching-upon-have-check later to maint). + + * Fix to an ancient bug caused by an over-eager attempt for + optimization. + (merge a98f7fb366 rs/add-index-entry-optim-fix later to maint). + + * Pushing a ref whose name contains non-ASCII character with the + "--force-with-lease" option did not work over smart HTTP protocol, + which has been corrected. + (merge cd85b447bf bc/push-cas-cquoted-refname later to maint). + + * "git mv src dst", when src is an unmerged path, errored out + correctly but with an incorrect error message to claim that src is + not tracked, which has been clarified. + (merge 9b906af657 ct/mv-unmerged-path-error later to maint). + + * Fix to a regression introduced during 2.27 cycle. + (merge cada7308ad en/fill-directory-exponential later to maint). + + * Command line completion (in contrib/) update. + (merge 688b87c81b mp/complete-show-color-moved later to maint). + + * All "mergy" operations that internally use the merge-recursive + machinery should honor the merge.renormalize configuration, but + many of them didn't. + + * Doc cleanup around "worktree". + (merge dc9c144be5 es/worktree-doc-cleanups later to maint). + + * The "git blame --first-parent" option was not documented, but now + it is. + (merge 11bc12ae1e rp/blame-first-parent-doc later to maint). + + * The logic to find the ref transaction hook script attempted to + cache the path to the found hook without realizing that it needed + to keep a copied value, as the API it used returned a transitory + buffer space. This has been corrected. + (merge 09b2aa30c9 ps/ref-transaction-hook later to maint). + + * Recent versions of "git diff-files" shows a diff between the index + and the working tree for "intent-to-add" paths as a "new file" + patch; "git apply --cached" should be able to take "git diff-files" + and should act as an equivalent to "git add" for the path, but the + command failed to do so for such a path. + (merge 4c025c667e rp/apply-cached-with-i-t-a later to maint). + + * "git diff [<tree-ish>] $path" for a $path that is marked with i-t-a + bit was not showing the mode bits from the working tree. + (merge cb0dd22b82 rp/ita-diff-modefix later to maint). + + * Ring buffer with size 4 used for bin-hex translation resulted in a + wrong object name in the sequencer's todo output, which has been + corrected. + (merge 5da69c0dac ak/sequencer-fix-find-uniq-abbrev later to maint). + + * When given more than one target line ranges, "git blame -La,b + -Lc,d" was over-eager to coalesce groups of original lines and + showed incorrect results, which has been corrected. + (merge c2ebaa27d6 jk/blame-coalesce-fix later to maint). + + * The regexp to identify the function boundary for FORTRAN programs + has been updated. + (merge 75c3b6b2e8 pb/userdiff-fortran-update later to maint). + + * A few end-user facing messages have been updated to be + hash-algorithm agnostic. + (merge 4279000d3e jc/object-names-are-not-sha-1 later to maint). + + * "unlink" emulation on MinGW has been optimized. + (merge 680e0b4524 jh/mingw-unlink later to maint). + + * The purpose of "git init --separate-git-dir" is to initialize a + new project with the repository separate from the working tree, + or, in the case of an existing project, to move the repository + (the .git/ directory) out of the working tree. It does not make + sense to use --separate-git-dir with a bare repository for which + there is no working tree, so disallow its use with bare + repositories. + (merge ccf236a23a es/init-no-separate-git-dir-in-bare later to maint). + + * "ls-files -o" mishandled the top-level directory of another git + working tree that hangs in the current git working tree. + (merge ab282aa548 en/dir-nonbare-embedded later to maint). + + * Fix some incorrect UNLEAK() annotations. + (merge 3e19816dc0 jk/unleak-fixes later to maint). + + * Use more buffered I/O where we used to call many small write(2)s. + (merge a698d67b08 rs/more-buffered-io later to maint). + + * The patch-id computation did not ignore the "incomplete last line" + marker like whitespaces. + (merge 82a62015a7 rs/patch-id-with-incomplete-line later to maint). + + * Updates into a lazy/partial clone with a submodule did not work + well with transfer.fsckobjects set. + + * The parser for "git for-each-ref --format=..." was too loose when + parsing the "%(trailers...)" atom, and forgot that "trailers" and + "trailers:<modifiers>" are the only two allowed forms, which has + been corrected. + (merge 2c22e102f8 hv/ref-filter-trailers-atom-parsing-fix later to maint). + + * Long ago, we decided to use 3 threads by default when running the + index-pack task in parallel, which has been adjusted a bit upwards. + (merge fbff95b67f jk/index-pack-w-more-threads later to maint). + + * "git restore/checkout --no-overlay" with wildcarded pathspec + mistakenly removed matching paths in subdirectories, which has been + corrected. + (merge bfda204ade rs/checkout-no-overlay-pathspec-fix later to maint). + + * The description of --cached/--index options in "git apply --help" + has been updated. + (merge d064702be3 rp/apply-cached-doc later to maint). + + * Feeding "$ZERO_OID" to "git log --ignore-missing --stdin", and + running "git log --ignore-missing $ZERO_OID" fell back to start + digging from HEAD; it has been corrected to become a no-op, like + "git log --tags=no-tag-matches-this-pattern" does. + (merge 04a0e98515 jk/rev-input-given-fix later to maint). + + * Various callers of run_command API have been modernized. + (merge afbdba391e jc/run-command-use-embedded-args later to maint). + + * List of options offered and accepted by "git add -i/-p" were + inconsistent, which have been corrected. + (merge ce910287e7 pw/add-p-allowed-options-fix later to maint). + + * "git diff --stat -w" showed 0-line changes for paths whose changes + were only whitespaces, which was not intuitive. We now omit such + paths from the stat output. + (merge 1cf3d5db9b mr/diff-hide-stat-wo-textual-change later to maint). + + * It was possible for xrealloc() to send a non-NULL pointer that has + been freed, which has been fixed. + (merge 6479ea4a8a jk/xrealloc-avoid-use-after-free later to maint). + + * "git status" has trouble showing where it came from by interpreting + reflog entries that record certain events, e.g. "checkout @{u}", and + gives a hard/fatal error. Even though it inherently is impossible + to give a correct answer because the reflog entries lose some + information (e.g. "@{u}" does not record what branch the user was + on hence which branch 'the upstream' needs to be computed, and even + if the record were available, the relationship between branches may + have changed), at least hide the error and allow "status" to show its + output. + + * "git status --short" quoted a path with SP in it when tracked, but + not those that are untracked, ignored or unmerged. They are all + shown quoted consistently. + + * "git diff/show" on a change that involves a submodule used to read + the information on commits in the submodule from a wrong repository + and gave a wrong information when the commit-graph is involved. + (merge 85a1ec2c32 mf/submodule-summary-with-correct-repository later to maint). + + * Unlike "git config --local", "git config --worktree" did not fail + early and cleanly when started outside a git repository. + (merge 378fe5fc3d mt/config-fail-nongit-early later to maint). + + * There is a logic to estimate how many objects are in the + repository, which is meant to run once per process invocation, but + it ran every time the estimated value was requested. + (merge 67bb65de5d jk/dont-count-existing-objects-twice later to maint). + + * "git remote set-head" that failed still said something that hints + the operation went through, which was misleading. + (merge 5a07c6c3c2 cs/don-t-pretend-a-failed-remote-set-head-succeeded later to maint). + + * "git fetch --all --ipv4/--ipv6" forgot to pass the protocol options + to instances of the "git fetch" that talk to individual remotes, + which has been corrected. + (merge 4e735c1326 ar/fetch-ipversion-in-all later to maint). + + * The "unshelve" subcommand of "git p4" incorrectly used commit^N + where it meant to say commit~N to name the Nth generation + ancestor, which has been corrected. + (merge 0acbf5997f ld/p4-unshelve-fix later to maint). + + * "git clone" that clones from SHA-1 repository, while + GIT_DEFAULT_HASH set to use SHA-256 already, resulted in an + unusable repository that half-claims to be SHA-256 repository + with SHA-1 objects and refs. This has been corrected. + + * Adjust sample hooks for hash algorithm other than SHA-1. + (merge d8d3d632f4 dl/zero-oid-in-hooks later to maint). + + * "git range-diff" showed incorrect diffstat, which has been + corrected. + + * Earlier we taught "git pull" to warn when the user does not say the + histories need to be merged, rebased or accepts only fast- + forwarding, but the warning triggered for those who have set the + pull.ff configuration variable. + (merge 54200cef86 ah/pull later to maint). + + * Compilation fix around type punning. + (merge 176380fd11 jk/drop-unaligned-loads later to maint). + + * "git blame --ignore-rev/--ignore-revs-file" failed to validate + their input are valid revision, and failed to take into account + that the user may want to give an annotated tag instead of a + commit, which has been corrected. + (merge 610e2b9240 jc/blame-ignore-fix later to maint). + + * "git bisect start X Y", when X and Y are not valid committish + object names, should take X and Y as pathspec, but didn't. + (merge 73c6de06af cc/bisect-start-fix later to maint). + + * The explanation of the "scissors line" has been clarified. + (merge 287416dba6 eg/mailinfo-doc-scissors later to maint). + + * A race that leads to an access to a free'd data was corrected in + the codepath that reads pack files. + (merge bda959c476 mt/delta-base-cache-races later to maint). + + * in_merge_bases_many(), a way to see if a commit is reachable from + any commit in a set of commits, was totally broken when the + commit-graph feature was in use, which has been corrected. + (merge 8791bf1841 ds/in-merge-bases-many-optim-bug later to maint). + + * "git submodule update --quiet" did not squelch underlying "rebase" + and "pull" commands. + (merge 3ad0401e9e td/submodule-update-quiet later to maint). + + * The lazy fetching done internally to make missing objects available + in a partial clone incorrectly made permanent damage to the partial + clone filter in the repository, which has been corrected. + + * "log -c --find-object=X" did not work well to find a merge that + involves a change to an object X from only one parent. + (merge 957876f17d jk/diff-cc-oidfind-fix later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 84544f2ea3 sk/typofixes later to maint). + (merge b17f411ab5 ar/help-guides-doc later to maint). + (merge 98c6871fad rs/grep-simpler-parse-object-or-die-call later to maint). + (merge 861c4ce141 en/typofixes later to maint). + (merge 60e47f6773 sg/ci-git-path-fix-with-pyenv later to maint). + (merge e2bfa50ac3 jb/doc-packfile-name later to maint). + (merge 918d8ff780 es/worktree-cleanup later to maint). + (merge dc156bc31f ma/t1450-quotefix later to maint). + (merge 56e743426b en/merge-recursive-comment-fixes later to maint). + (merge 7d23ff818f rs/bisect-oid-to-hex-fix later to maint). + (merge de20baf2c9 ny/notes-doc-sample-update later to maint). + (merge f649aaaf82 so/rev-parser-errormessage-fix later to maint). + (merge 6103d58b7f bc/sha-256-cvs-svn-updates later to maint). + (merge ac900fddb7 ma/stop-progress-null-fix later to maint). + (merge e767963ab6 rs/upload-pack-sigchain-fix later to maint). + (merge a831908599 rs/preserve-merges-unused-code-removal later to maint). + (merge 6dfefe70a9 jb/commit-graph-doc-fix later to maint). + (merge 847b37271e pb/set-url-docfix later to maint). + (merge 748f733d54 mt/checkout-entry-dead-code-removal later to maint). + (merge ce820cbd58 dl/subtree-docs later to maint). + (merge 55fe225dde jk/leakfix later to maint). + (merge ee22a29215 so/pretty-abbrev-doc later to maint). + (merge 3100fd5588 jc/post-checkout-doc later to maint). + (merge 17bae89476 pb/doc-external-diff-env later to maint). + (merge 27ed6ccc12 jk/worktree-check-clean-leakfix later to maint). + (merge 1302badd16 ea/blame-use-oideq later to maint). + (merge e6d5a11fed al/t3200-back-on-a-branch later to maint). + (merge 324efcf6b6 pw/add-p-leakfix later to maint). + (merge 1c6ffb546b jk/add-i-fixes later to maint). + (merge e40e936551 cd/commit-graph-doc later to maint). + (merge 0512eabd91 jc/sequencer-stopped-sha-simplify later to maint). + (merge d01141de5a so/combine-diff-simplify later to maint). + (merge 3be01e5ab1 sn/fast-import-doc later to maint). diff --git a/Documentation/RelNotes/2.29.1.txt b/Documentation/RelNotes/2.29.1.txt new file mode 100644 index 0000000000..295ee2135f --- /dev/null +++ b/Documentation/RelNotes/2.29.1.txt @@ -0,0 +1,11 @@ +Git v2.29.1 Release Notes +========================= + +This is to fix the build procedure change in 2.28 where we failed to +install a few programs that should be installed in /usr/bin (namely, +receive-pack, upload-archive and upload-pack) when the non-default +SKIP_DASHED_BUILT_INS installation option is in effect. + +A minor glitch in a non-default installation may usually not deserve +a hotfix, but I know Git for Windows ship binaries built with this +option, so let's make an exception. diff --git a/Documentation/RelNotes/2.29.2.txt b/Documentation/RelNotes/2.29.2.txt new file mode 100644 index 0000000000..632b5b580a --- /dev/null +++ b/Documentation/RelNotes/2.29.2.txt @@ -0,0 +1,12 @@ +Git v2.29.2 Release Notes +========================= + +This release is primarily to fix brown-paper-bag breakages in the +2.29.0 release. + +Fixes since v2.29.1 +------------------- + + * In 2.29, "--committer-date-is-author-date" option of "rebase" and + "am" subcommands lost the e-mail address by mistake, which has been + corrected. diff --git a/Documentation/RelNotes/2.29.3.txt b/Documentation/RelNotes/2.29.3.txt new file mode 100644 index 0000000000..e10eedb35a --- /dev/null +++ b/Documentation/RelNotes/2.29.3.txt @@ -0,0 +1,8 @@ +Git v2.29.3 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, +v2.18.5, v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, +v2.25.5, v2.26.3, v2.27.1 and v2.28.1 to address the security +issue CVE-2021-21300; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.3.3.txt b/Documentation/RelNotes/2.3.3.txt index 5ef12644c2..850dc68ede 100644 --- a/Documentation/RelNotes/2.3.3.txt +++ b/Documentation/RelNotes/2.3.3.txt @@ -12,7 +12,7 @@ Fixes since v2.3.2 * Description given by "grep -h" for its --exclude-standard option was phrased poorly. - * Documentaton for "git remote add" mentioned "--tags" and + * Documentation for "git remote add" mentioned "--tags" and "--no-tags" and it was not clear that fetch from the remote in the future will use the default behaviour when neither is given to override it. diff --git a/Documentation/RelNotes/2.3.7.txt b/Documentation/RelNotes/2.3.7.txt index fc95812cb3..5769184081 100644 --- a/Documentation/RelNotes/2.3.7.txt +++ b/Documentation/RelNotes/2.3.7.txt @@ -4,7 +4,7 @@ Git v2.3.7 Release Notes Fixes since v2.3.6 ------------------ - * An earlier update to the parser that disects a URL broke an + * An earlier update to the parser that dissects a URL broke an address, followed by a colon, followed by an empty string (instead of the port number), e.g. ssh://example.com:/path/to/repo. diff --git a/Documentation/RelNotes/2.30.0.txt b/Documentation/RelNotes/2.30.0.txt new file mode 100644 index 0000000000..c2f1dc7b06 --- /dev/null +++ b/Documentation/RelNotes/2.30.0.txt @@ -0,0 +1,401 @@ +Git 2.30 Release Notes +====================== + +Updates since v2.29 +------------------- + +UI, Workflows & Features + + * Userdiff for PHP update. + + * Userdiff for Rust update. + + * Userdiff for CSS update. + + * The command line completion script (in contrib/) learned that "git + stash show" takes the options "git diff" takes. + + * "git worktree list" now shows if each worktree is locked. This + possibly may open us to show other kinds of states in the future. + + * "git maintenance", an extended big brother of "git gc", continues + to evolve. + + * "git push --force-with-lease[=<ref>]" can easily be misused to lose + commits unless the user takes good care of their own "git fetch". + A new option "--force-if-includes" attempts to ensure that what is + being force-pushed was created after examining the commit at the + tip of the remote ref that is about to be force-replaced. + + * "git clone" learned clone.defaultremotename configuration variable + to customize what nickname to use to call the remote the repository + was cloned from. + + * "git checkout" learned to use checkout.guess configuration variable + and enable/disable its "--[no-]guess" option accordingly. + + * "git resurrect" script (in contrib/) learned that the object names + may be longer than 40-hex depending on the hash function in use. + + * "git diff A...B" learned "git diff --merge-base A B", which is a + longer short-hand to say the same thing. + + * A sample 'push-to-checkout' hook, that performs the same as + what the built-in default action does, has been added. + + * "git diff" family of commands learned the "-I<regex>" option to + ignore hunks whose changed lines all match the given pattern. + + * The userdiff pattern learned to identify the function definition in + POSIX shells and bash. + + * "git checkout-index" did not consistently signal an error with its + exit status, but now it does. + + * A commit and tag object may have CR at the end of each and + every line (you can create such an object with hash-object or + using --cleanup=verbatim to decline the default clean-up + action), but it would make it impossible to have a blank line + to separate the title from the body of the message. We are now + more lenient and accept a line with lone CR on it as a blank line, + too. + + * Exit codes from "git remote add" etc. were not usable by scripted + callers, but now they are. + + * "git archive" now allows compression level higher than "-9" + when generating tar.gz output. + + * Zsh autocompletion (in contrib/) update. + + * The maximum length of output filenames "git format-patch" creates + has become configurable (used to be capped at 64). + + * "git rev-parse" learned the "--end-of-options" to help scripts to + safely take a parameter that is supposed to be a revision, e.g. + "git rev-parse --verify -q --end-of-options $rev". + + * The command line completion script (in contrib/) learned to expand + commands that are alias of alias. + + * "git update-ref --stdin" learns to take multiple transactions in a + single session. + + * Various subcommands of "git config" that take value_regex + learned the "--literal-value" option to take the value_regex option + as a literal string. + + * The transport layer was taught to optionally exchange the session + ID assigned by the trace2 subsystem during fetch/push transactions. + + * "git imap-send" used to ignore configuration variables like + core.askpass; this has been corrected. + + * "git $cmd $args", when $cmd is not a recognised subcommand, by + default tries to see if $cmd is a typo of an existing subcommand + and optionally executes the corrected command if there is only one + possibility, depending on the setting of help.autocorrect; the + users can now disable the whole thing, including the cycles spent + to find a likely typo, by setting the configuration variable to + 'never'. + + * "@" sometimes worked (e.g. "git push origin @:there") as a part of + a refspec element, but "git push origin @" did not work, which has + been corrected. + + +Performance, Internal Implementation, Development Support etc. + + * Use "git archive" more to produce the release tarball. + + * GitHub Actions automated test improvement to skip tests on a tree + identical to what has already been tested. + + * Test-coverage for running commit-graph task "git maintenance" has + been extended. + + * Our test scripts can be told to run only individual pieces while + skipping others with the "--run=..." option; they were taught to + take a substring of test title, in addition to numbers, to name the + test pieces to run. + + * Adjust tests so that they won't scream when the default initial + branch name is different from 'master'. + + * Rewriting "git bisect" in C continues. + + * More preliminary tests have been added to document desired outcomes + of various "directory rename" situations. + + * Micro clean-up of a couple of test scripts. + + * "git diff" and other commands that share the same machinery to + compare with working tree files have been taught to take advantage + of the fsmonitor data when available. + + * The code to detect premature EOF in the sideband demultiplexer has + been cleaned up. + + * "git fetch --depth=<n>" over the stateless RPC / smart HTTP + transport handled EOF from the client poorly at the server end. + + * A specialization of hashmap that uses a string as key has been + introduced. Hopefully it will see wider use over time. + + * "git bisect start/next" in a large span of history spends a lot of + time trying to come up with exactly the half-way point; this can be + optimized by stopping when we see a commit that is close enough to + the half-way point. + + * A lazily defined test prerequisite can now be defined in terms of + another lazily defined test prerequisite. + + * Expectation for the original contributor after responding to a + review comment to use the explanation in a patch update has been + described. + + * Multiple "credential-store" backends can race to lock the same + file, causing everybody else but one to fail---reattempt locking + with some timeout to reduce the rate of the failure. + + * "git-parse-remote" shell script library outlived its usefulness. + + * Like die() and error(), a call to warning() will also trigger a + trace2 event. + + * Use of non-reentrant localtime() has been removed. + + * Non-reentrant time-related library functions and ctime/asctime with + awkward calling interfaces are banned from the codebase. + + +Fixes since v2.29 +----------------- + + * In 2.29, "--committer-date-is-author-date" option of "rebase" and + "am" subcommands lost the e-mail address by mistake, which has been + corrected. + (merge 5f35edd9d7 jk/committer-date-is-author-date-fix later to maint). + + * "git checkout -p A...B [-- <path>]" did not work, even though the + same command without "-p" correctly used the merge-base between + commits A and B. + (merge 35166b1fb5 dl/checkout-p-merge-base later to maint). + + * The side-band status report can be sent at the same time as the + primary payload multiplexed, but the demultiplexer on the receiving + end incorrectly split a single status report into two, which has + been corrected. + (merge 712b0377db js/avoid-split-sideband-message later to maint). + + * "git fast-import" wasted a lot of memory when many marks were in use. + (merge 3f018ec716 jk/fast-import-marks-alloc-fix later to maint). + + * A test helper "test_cmp A B" was taught to diagnose missing files A + or B as a bug in test, but some tests legitimately wanted to notice + a failure to even create file B as an error, in addition to leaving + the expected result in it, and were misdiagnosed as a bug. This + has been corrected. + (merge 262d5ad5a5 es/test-cmp-typocatcher later to maint). + + * When "git commit-graph" detects the same commit recorded more than + once while it is merging the layers, it used to die. The code now + ignores all but one of them and continues. + (merge 85102ac71b ds/commit-graph-merging-fix later to maint). + + * The meaning of a Signed-off-by trailer can vary from project to + project; this and also what it means to this project has been + clarified in the documentation. + (merge 3abd4a67d9 bk/sob-dco later to maint). + + * "git credential' didn't honor the core.askPass configuration + variable (among other things), which has been corrected. + (merge 567ad2c0f9 tk/credential-config later to maint). + + * Dev support to catch a tentative definition of a variable in our C + code as an error. + (merge 5539183622 jk/no-common later to maint). + + * "git rebase --rebase-merges" did not correctly pass --gpg-sign + command line option to underlying "git merge" when replaying a merge + using non-default merge strategy or when replaying an octopus merge + (because replaying a two-head merge with the default strategy was + done in a separate codepath, the problem did not trigger for most + users), which has been corrected. + (merge 43ad4f2eca sc/sequencer-gpg-octopus later to maint). + + * "git apply -R" did not handle patches that touch the same path + twice correctly, which has been corrected. This is most relevant + in a patch that changes a path from a regular file to a symbolic + link (and vice versa). + (merge b0f266de11 jt/apply-reverse-twice later to maint). + + * A recent oid->hash conversion missed one spot, breaking "git svn". + (merge 03bb366de4 bc/svn-hash-oid-fix later to maint). + + * The documentation on the "--abbrev=<n>" option did not say the + output may be longer than "<n>" hexdigits, which has been + clarified. + (merge cda34e0d0c jc/abbrev-doc later to maint). + + * "git p4" now honors init.defaultBranch configuration. + (merge 1b09d1917f js/p4-default-branch later to maint). + + * Recently the format of an internal state file "rebase -i" uses has + been tightened up for consistency, which would hurt those who start + "rebase -i" with old git and then continue with new git. Loosen + the reader side a bit (which we may want to tighten again in a year + or so). + (merge c779386182 jc/sequencer-stopped-sha-simplify later to maint). + + * The code to see if "git stash drop" can safely remove refs/stash + has been made more careful. + (merge 4f44c5659b rs/empty-reflog-check-fix later to maint). + + * "git log -L<range>:<path>" is documented to take no pathspec, but + this was not enforced by the command line option parser, which has + been corrected. + (merge 39664cb0ac jc/line-log-takes-no-pathspec later to maint). + + * "git format-patch --output=there" did not work as expected and + instead crashed. The option is now supported. + (merge dc1672dd10 jk/format-patch-output later to maint). + + * Define ARM64 compiled with MSVC to be little-endian. + (merge 0c038fc65a dg/bswap-msvc later to maint). + + * "git rebase -i" did not store ORIG_HEAD correctly. + (merge 8843302307 pw/rebase-i-orig-head later to maint). + + * "git blame -L :funcname -- path" did not work well for a path for + which a userdiff driver is defined. + + * "make DEVELOPER=1 sparse" used to run sparse and let it emit + warnings; now such warnings will cause an error. + (merge 521dc56270 jc/sparse-error-for-developer-build later to maint). + + * "git blame --ignore-revs-file=<file>" learned to ignore a + non-existent object name in the input, instead of complaining. + (merge c714d05875 jc/blame-ignore-fix later to maint). + + * Running "git diff" while allowing external diff in a state with + unmerged paths used to segfault, which has been corrected. + (merge d66851806f jk/diff-release-filespec-fix later to maint). + + * Build configuration cleanup. + (merge b990f02fd8 ab/config-mak-uname-simplify later to maint). + + * Fix regression introduced when nvimdiff support in mergetool was added. + (merge 12026f46e7 pd/mergetool-nvimdiff later to maint). + + * The exchange between receive-pack and proc-receive hook did not + carefully check for errors. + + * The code was not prepared to deal with pack .idx file that is + larger than 4GB. + (merge 81c4c5cf2e jk/4gb-idx later to maint). + + * Since jgit does not yet work with SHA-256 repositories, mark the + tests that use it not to run unless we are testing with ShA-1 + repositories. + (merge ea699b4adc sg/t5310-jgit-wants-sha1 later to maint). + + * Config parser fix for "git notes". + (merge 45fef1599a na/notes-displayref-is-not-boolean later to maint). + + * Move a definition of compatibility wrapper from cache.h to + git-compat-util.h + (merge a76b138daa hn/sleep-millisec-decl later to maint). + + * Error message fix. + (merge eaf5341538 km/stash-error-message-fix later to maint). + + * "git pull --rebase --recurse-submodules" checked for local changes + in a wrong range and failed to run correctly when it should. + (merge 5176f20ffe pb/pull-rebase-recurse-submodules later to maint). + + * "git push" that is killed may leave a pack-objects process behind, + still computing to find a good compression, wasting cycles. This + has been corrected. + (merge 8b59935114 jk/stop-pack-objects-when-push-is-killed later to maint). + + * "git fetch" that is killed may leave a pack-objects process behind, + still computing to find a good compression, wasting cycles. This + has been corrected. + (merge 309a4028e7 jk/stop-pack-objects-when-fetch-is-killed later to maint). + + * "git add -i" failed to honor custom colors configured to show + patches, which has been corrected. + (merge 96386faa03 js/add-i-color-fix later to maint). + + * Processes that access packdata while the .idx file gets removed + (e.g. while repacking) did not fail or fall back gracefully as they + could. + (merge 506ec2fbda tb/idx-midx-race-fix later to maint). + + * "git apply" adjusted the permission bits of working-tree files and + directories according to core.sharedRepository setting by mistake and + for a long time, which has been corrected. + (merge eb3c027e17 mt/do-not-use-scld-in-working-tree later to maint). + + * "fetch-pack" could pass NULL pointer to unlink(2) when it sees an + invalid filename; the error checking has been tightened to make + this impossible. + (merge 6031af387e rs/fetch-pack-invalid-lockfile later to maint). + + * "git maintenance run/start/stop" needed to be run in a repository + to hold the lockfile they use, but didn't make sure they are + actually in a repository, which has been corrected. + + * The glossary described a branch as an "active" line of development, + which is misleading---a stale and non-moving branch is still a + branch. + (merge eef1ceabd8 so/glossary-branch-is-not-necessarily-active later to maint). + + * Newer versions of xsltproc can assign IDs in HTML documents it + generates in a consistent manner. Use the feature to help format + HTML version of the user manual reproducibly. + (merge 3569e11d69 ae/doc-reproducible-html later to maint). + + * Tighten error checking in the codepath that responds to "git fetch". + (merge d43a21bdbb jk/check-config-parsing-error-in-upload-pack later to maint). + + * "git pack-redundant" when there is only one packfile used to crash, + which has been corrected. + (merge 0696232390 jx/pack-redundant-on-single-pack later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 3e0a5dc9af cc/doc-filter-branch-typofix later to maint). + (merge 32c83afc2c cw/ci-ghwf-check-ws-errors later to maint). + (merge 5eb2ed691b rs/tighten-callers-of-deref-tag later to maint). + (merge 6db29ab213 jk/fast-import-marks-cleanup later to maint). + (merge e5cf6d3df4 nk/dir-c-comment-update later to maint). + (merge 5710dcce74 jk/report-fn-typedef later to maint). + (merge 9a82db1056 en/sequencer-rollback-lock-cleanup later to maint). + (merge 4e1bee9a99 js/t7006-cleanup later to maint). + (merge f5bcde6c58 es/tutorial-mention-asciidoc-early later to maint). + (merge 714d491af0 so/format-patch-doc-on-default-diff-format later to maint). + (merge 0795df4b9b rs/clear-commit-marks-in-repo later to maint). + (merge 9542d56379 sd/prompt-local-variable later to maint). + (merge 06d43fad18 rs/pack-write-hashwrite-simplify later to maint). + (merge b7e20b4373 mc/typofix later to maint). + (merge f6bcd9a8a4 js/test-whitespace-fixes later to maint). + (merge 53b67a801b js/test-file-size later to maint). + (merge 970909c2a7 rs/hashwrite-be64 later to maint). + (merge 5a923bb1f0 ma/list-object-filter-opt-msgfix later to maint). + (merge 1c3e412916 rs/archive-plug-leak-refname later to maint). + (merge d44e5267ea rs/plug-diff-cache-leak later to maint). + (merge 793c1464d3 ab/gc-keep-base-option later to maint). + (merge b86339b12b mt/worktree-error-message-fix later to maint). + (merge e01ae2a4a7 js/pull-rebase-use-advise later to maint). + (merge e63d774242 sn/config-doc-typofix later to maint). + (merge 08e9df2395 jk/multi-line-indent-style-fix later to maint). + (merge e66590348a da/vs-build-iconv-fix later to maint). + (merge 7fe07275be js/cmake-extra-built-ins-fix later to maint). + (merge 633eebe142 jb/midx-doc-update later to maint). + (merge 5885367e8f jh/index-v2-doc-on-fsmn later to maint). + (merge 14639a4779 jc/compat-util-setitimer-fix later to maint). + (merge 56f56ac50b ab/unreachable-break later to maint). + (merge 731d578b4f rb/nonstop-config-mak-uname-update later to maint). + (merge f4698738f9 es/perf-export-fix later to maint). + (merge 773c694142 nk/refspecs-negative-fix later to maint). diff --git a/Documentation/RelNotes/2.30.1.txt b/Documentation/RelNotes/2.30.1.txt new file mode 100644 index 0000000000..249ef1492f --- /dev/null +++ b/Documentation/RelNotes/2.30.1.txt @@ -0,0 +1,55 @@ +Git v2.30.1 Release Notes +========================= + +This release is primarily to merge fixes accumulated on the 'master' +front to prepare for 2.31 release that are still relevant to 2.30.x +maintenance track. + +Fixes since v2.30 +----------------- + + * "git fetch --recurse-submodules" failed to update a submodule + when it has an uninitialized (hence of no interest to the user) + sub-submodule, which has been corrected. + + * Command line error of "git rebase" are diagnosed earlier. + + * "git stash" did not work well in a sparsely checked out working + tree. + + * Some tests expect that "ls -l" output has either '-' or 'x' for + group executable bit, but setgid bit can be inherited from parent + directory and make these fields 'S' or 's' instead, causing test + failures. + + * "git for-each-repo --config=<var> <cmd>" should not run <cmd> for + any repository when the configuration variable <var> is not defined + even once. + + * "git mergetool --tool-help" was broken in 2.29 and failed to list + all the available tools. + + * Fix for procedure to building CI test environment for mac. + + * Newline characters in the host and path part of git:// URL are + now forbidden. + + * When more than one commit with the same patch ID appears on one + side, "git log --cherry-pick A...B" did not exclude them all when a + commit with the same patch ID appears on the other side. Now it + does. + + * Documentation for "git fsck" lost stale bits that has become + incorrect. + + * Doc for packfile URI feature has been clarified. + + * The implementation of "git branch --sort" wrt the detached HEAD + display has always been hacky, which has been cleaned up. + + * Our setting of GitHub CI test jobs were a bit too eager to give up + once there is even one failure found. Tweak the knob to allow + other jobs keep running even when we see a failure, so that we can + find more failures in a single run. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.30.2.txt b/Documentation/RelNotes/2.30.2.txt new file mode 100644 index 0000000000..bada398501 --- /dev/null +++ b/Documentation/RelNotes/2.30.2.txt @@ -0,0 +1,8 @@ +Git v2.30.2 Release Notes +========================= + +This release merges up the fixes that appear in v2.17.6, v2.18.5, +v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, v2.25.5, +v2.26.3, v2.27.1, v2.28.1 and v2.29.3 to address the security +issue CVE-2021-21300; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.31.0.txt b/Documentation/RelNotes/2.31.0.txt new file mode 100644 index 0000000000..cf0c7d8d40 --- /dev/null +++ b/Documentation/RelNotes/2.31.0.txt @@ -0,0 +1,365 @@ +Git 2.31 Release Notes +====================== + +Updates since v2.30 +------------------- + +Backward incompatible and other important changes + + * The "pack-redundant" command, which has been left stale with almost + unusable performance issues, now warns loudly when it gets used, as + we no longer want to recommend its use (instead just "repack -d" + instead). + + * The development community has adopted Contributor Covenant v2.0 to + update from v1.4 that we have been using. + + * The support for deprecated PCRE1 library has been dropped. + + * Fixes for CVE-2021-21300 in Git 2.30.2 (and earlier) is included. + + +UI, Workflows & Features + + * The "--format=%(trailers)" mechanism gets enhanced to make it + easier to design output for machine consumption. + + * When a user does not tell "git pull" to use rebase or merge, the + command gives a loud message telling a user to choose between + rebase or merge but creates a merge anyway, forcing users who would + want to rebase to redo the operation. Fix an early part of this + problem by tightening the condition to give the message---there is + no reason to stop or force the user to choose between rebase or + merge if the history fast-forwards. + + * The configuration variable 'core.abbrev' can be set to 'no' to + force no abbreviation regardless of the hash algorithm. + + * "git rev-parse" can be explicitly told to give output as absolute + or relative path with the `--path-format=(absolute|relative)` option. + + * Bash completion (in contrib/) update to make it easier for + end-users to add completion for their custom "git" subcommands. + + * "git maintenance" learned to drive scheduled maintenance on + platforms whose native scheduling methods are not 'cron'. + + * After expiring a reflog and making a single commit, the reflog for + the branch would record a single entry that knows both @{0} and + @{1}, but we failed to answer "what commit were we on?", i.e. @{1} + + * "git bundle" learns "--stdin" option to read its refs from the + standard input. Also, it now does not lose refs whey they point + at the same object. + + * "git log" learned a new "--diff-merges=<how>" option. + + * "git ls-files" can and does show multiple entries when the index is + unmerged, which is a source for confusion unless -s/-u option is in + use. A new option --deduplicate has been introduced. + + * `git worktree list` now annotates worktrees as prunable, shows + locked and prunable attributes in --porcelain mode, and gained + a --verbose option. + + * "git clone" tries to locally check out the branch pointed at by + HEAD of the remote repository after it is done, but the protocol + did not convey the information necessary to do so when copying an + empty repository. The protocol v2 learned how to do so. + + * There are other ways than ".." for a single token to denote a + "commit range", namely "<rev>^!" and "<rev>^-<n>", but "git + range-diff" did not understand them. + + * The "git range-diff" command learned "--(left|right)-only" option + to show only one side of the compared range. + + * "git mergetool" feeds three versions (base, local and remote) of + a conflicted path unmodified. The command learned to optionally + prepare these files with unconflicted parts already resolved. + + * The .mailmap is documented to be read only from the root level of a + working tree, but a stray file in a bare repository also was read + by accident, which has been corrected. + + * "git maintenance" tool learned a new "pack-refs" maintenance task. + + * The error message given when a configuration variable that is + expected to have a boolean value has been improved. + + * Signed commits and tags now allow verification of objects, whose + two object names (one in SHA-1, the other in SHA-256) are both + signed. + + * "git rev-list" command learned "--disk-usage" option. + + * "git {diff,log} --{skip,rotate}-to=<path>" allows the user to + discard diff output for early paths or move them to the end of the + output. + + * "git difftool" learned "--skip-to=<path>" option to restart an + interrupted session from an arbitrary path. + + * "git grep" has been tweaked to be limited to the sparse checkout + paths. + + * "git rebase --[no-]fork-point" gained a configuration variable + rebase.forkPoint so that users do not have to keep specifying a + non-default setting. + + +Performance, Internal Implementation, Development Support etc. + + * A 3-year old test that was not testing anything useful has been + corrected. + + * Retire more names with "sha1" in it. + + * The topological walk codepath is covered by new trace2 stats. + + * Update the Code-of-conduct to version 2.0 from the upstream (we've + been using version 1.4). + + * "git mktag" validates its input using its own rules before writing + a tag object---it has been updated to share the logic with "git + fsck". + + * Two new ways to feed configuration variable-value pairs via + environment variables have been introduced, and the way + GIT_CONFIG_PARAMETERS encodes variable/value pairs has been tweaked + to make it more robust. + + * Tests have been updated so that they do not to get affected by the + name of the default branch "git init" creates. + + * "git fetch" learns to treat ref updates atomically in all-or-none + fashion, just like "git push" does, with the new "--atomic" option. + + * The peel_ref() API has been replaced with peel_iterated_oid(). + + * The .use_shell flag in struct child_process that is passed to + run_command() API has been clarified with a bit more documentation. + + * Document, clean-up and optimize the code around the cache-tree + extension in the index. + + * The ls-refs protocol operation has been optimized to narrow the + sub-hierarchy of refs/ it walks to produce response. + + * When removing many branches and tags, the code used to do so one + ref at a time. There is another API it can use to delete multiple + refs, and it makes quite a lot of performance difference when the + refs are packed. + + * The "pack-objects" command needs to iterate over all the tags when + automatic tag following is enabled, but it actually iterated over + all refs and then discarded everything outside "refs/tags/" + hierarchy, which was quite wasteful. + + * A perf script was made more portable. + + * Our setting of GitHub CI test jobs were a bit too eager to give up + once there is even one failure found. Tweak the knob to allow + other jobs keep running even when we see a failure, so that we can + find more failures in a single run. + + * We've carried compatibility codepaths for compilers without + variadic macros for quite some time, but the world may be ready for + them to be removed. Force compilation failure on exotic platforms + where variadic macros are not available to find out who screams in + such a way that we can easily revert if it turns out that the world + is not yet ready. + + * Code clean-up to ensure our use of hashtables using object names as + keys use the "struct object_id" objects, not the raw hash values. + + * Lose the debugging aid that may have been useful in the past, but + no longer is, in the "grep" codepaths. + + * Some pretty-format specifiers do not need the data in commit object + (e.g. "%H"), but we were over-eager to load and parse it, which has + been made even lazier. + + * Get rid of "GETTEXT_POISON" support altogether, which may or may + not be controversial. + + * Introduce an on-disk file to record revindex for packdata, which + traditionally was always created on the fly and only in-core. + + * The commit-graph learned to use corrected commit dates instead of + the generation number to help topological revision traversal. + + * Piecemeal of rewrite of "git bisect" in C continues. + + * When a pager spawned by us exited, the trace log did not record its + exit status correctly, which has been corrected. + + * Removal of GIT_TEST_GETTEXT_POISON continues. + + * The code to implement "git merge-base --independent" was poorly + done and was kept from the very beginning of the feature. + + * Preliminary changes to fsmonitor integration. + + * Performance improvements for rename detection. + + * The common code to deal with "chunked file format" that is shared + by the multi-pack-index and commit-graph files have been factored + out, to help codepaths for both filetypes to become more robust. + + * The approach to "fsck" the incoming objects in "index-pack" is + attractive for performance reasons (we have them already in core, + inflated and ready to be inspected), but fundamentally cannot be + applied fully when we receive more than one pack stream, as a tree + object in one pack may refer to a blob object in another pack as + ".gitmodules", when we want to inspect blobs that are used as + ".gitmodules" file, for example. Teach "index-pack" to emit + objects that must be inspected later and check them in the calling + "fetch-pack" process. + + * The logic to handle "trailer" related placeholders in the + "--format=" mechanisms in the "log" family and "for-each-ref" + family is getting unified. + + * Raise the buffer size used when writing the index file out from + (obviously too small) 8kB to (clearly sufficiently large) 128kB. + + * It is reported that open() on some platforms (e.g. macOS Big Sur) + can return EINTR even though our timers are set up with SA_RESTART. + A workaround has been implemented and enabled for macOS to rerun + open() transparently from the caller when this happens. + + +Fixes since v2.30 +----------------- + + * Diagnose command line error of "git rebase" early. + + * Clean up option descriptions in "git cmd --help". + + * "git stash" did not work well in a sparsely checked out working + tree. + + * Some tests expect that "ls -l" output has either '-' or 'x' for + group executable bit, but setgid bit can be inherited from parent + directory and make these fields 'S' or 's' instead, causing test + failures. + + * "git for-each-repo --config=<var> <cmd>" should not run <cmd> for + any repository when the configuration variable <var> is not defined + even once. + + * Fix 2.29 regression where "git mergetool --tool-help" fails to list + all the available tools. + + * Fix for procedure to building CI test environment for mac. + + * The implementation of "git branch --sort" wrt the detached HEAD + display has always been hacky, which has been cleaned up. + + * Newline characters in the host and path part of git:// URL are + now forbidden. + + * "git diff" showed a submodule working tree with untracked cruft as + "Submodule commit <objectname>-dirty", but a natural expectation is + that the "-dirty" indicator would align with "git describe --dirty", + which does not consider having untracked files in the working tree + as source of dirtiness. The inconsistency has been fixed. + + * When more than one commit with the same patch ID appears on one + side, "git log --cherry-pick A...B" did not exclude them all when a + commit with the same patch ID appears on the other side. Now it + does. + + * Documentation for "git fsck" lost stale bits that has become + incorrect. + + * Doc fix for packfile URI feature. + + * When "git rebase -i" processes "fixup" insn, there is no reason to + clean up the commit log message, but we did the usual stripspace + processing. This has been corrected. + (merge f7d42ceec5 js/rebase-i-commit-cleanup-fix later to maint). + + * Fix in passing custom args from "git clone" to "upload-pack" on the + other side. + (merge ad6b5fefbd jv/upload-pack-filter-spec-quotefix later to maint). + + * The command line completion (in contrib/) completed "git branch -d" + with branch names, but "git branch -D" offered tagnames in addition, + which has been corrected. "git branch -M" had the same problem. + (merge 27dc071b9a jk/complete-branch-force-delete later to maint). + + * When commands are started from a subdirectory, they may have to + compare the path to the subdirectory (called prefix and found out + from $(pwd)) with the tracked paths. On macOS, $(pwd) and + readdir() yield decomposed path, while the tracked paths are + usually normalized to the precomposed form, causing mismatch. This + has been fixed by taking the same approach used to normalize the + command line arguments. + (merge 5c327502db tb/precompose-prefix-too later to maint). + + * Even though invocations of "die()" were logged to the trace2 + system, "BUG()"s were not, which has been corrected. + (merge 0a9dde4a04 jt/trace2-BUG later to maint). + + * "git grep --untracked" is meant to be "let's ALSO find in these + files on the filesystem" when looking for matches in the working + tree files, and does not make any sense if the primary search is + done against the index, or the tree objects. The "--cached" and + "--untracked" options have been marked as mutually incompatible. + (merge 0c5d83b248 mt/grep-cached-untracked later to maint). + + * Fix "git fsck --name-objects" which apparently has not been used by + anybody who is motivated enough to report breakage. + (merge e89f89361c js/fsck-name-objects-fix later to maint). + + * Avoid individual tests in t5411 from getting affected by each other + by forcing them to use separate output files during the test. + (merge 822ee894f6 jx/t5411-unique-filenames later to maint). + + * Test to make sure "git rev-parse one-thing one-thing" gives + the same thing twice (when one-thing is --since=X). + (merge a5cdca4520 ew/rev-parse-since-test later to maint). + + * When certain features (e.g. grafts) used in the repository are + incompatible with the use of the commit-graph, we used to silently + turned commit-graph off; we now tell the user what we are doing. + (merge c85eec7fc3 js/commit-graph-warning later to maint). + + * Objects that lost references can be pruned away, even when they + have notes attached to it (and these notes will become dangling, + which in turn can be pruned with "git notes prune"). This has been + clarified in the documentation. + (merge fa9ab027ba mz/doc-notes-are-not-anchors later to maint). + + * The error codepath around the "--temp/--prefix" feature of "git + checkout-index" has been improved. + (merge 3f7ba60350 mt/checkout-index-corner-cases later to maint). + + * The "git maintenance register" command had trouble registering bare + repositories, which had been corrected. + + * A handful of multi-word configuration variable names in + documentation that are spelled in all lowercase have been corrected + to use the more canonical camelCase. + (merge 7dd0eaa39c dl/doc-config-camelcase later to maint). + + * "git push $there --delete ''" should have been diagnosed as an + error, but instead turned into a matching push, which has been + corrected. + (merge 20e416409f jc/push-delete-nothing later to maint). + + * Test script modernization. + (merge 488acf15df sv/t7001-modernize later to maint). + + * An under-allocation for the untracked cache data has been corrected. + (merge 6347d649bc jh/untracked-cache-fix later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge e3f5da7e60 sg/t7800-difftool-robustify later to maint). + (merge 9d336655ba js/doc-proto-v2-response-end later to maint). + (merge 1b5b8cf072 jc/maint-column-doc-typofix later to maint). + (merge 3a837b58e3 cw/pack-config-doc later to maint). + (merge 01168a9d89 ug/doc-commit-approxidate later to maint). + (merge b865734760 js/params-vs-args later to maint). diff --git a/Documentation/RelNotes/2.31.1.txt b/Documentation/RelNotes/2.31.1.txt new file mode 100644 index 0000000000..f9b06b8e1b --- /dev/null +++ b/Documentation/RelNotes/2.31.1.txt @@ -0,0 +1,27 @@ +Git 2.31.1 Release Notes +======================== + +Fixes since v2.31 +----------------- + + * The fsmonitor interface read from its input without making sure + there is something to read from. This bug is new in 2.31 + timeframe. + + * The data structure used by fsmonitor interface was not properly + duplicated during an in-core merge, leading to use-after-free etc. + + * "git bisect" reimplemented more in C during 2.30 timeframe did not + take an annotated tag as a good/bad endpoint well. This regression + has been corrected. + + * Fix macros that can silently inject unintended null-statements. + + * CALLOC_ARRAY() macro replaces many uses of xcalloc(). + + * Update insn in Makefile comments to run fuzz-all target. + + * Fix a corner case bug in "git mv" on case insensitive systems, + which was introduced in 2.29 timeframe. + +Also contains various documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.32.0.txt b/Documentation/RelNotes/2.32.0.txt new file mode 100644 index 0000000000..87d56fa1aa --- /dev/null +++ b/Documentation/RelNotes/2.32.0.txt @@ -0,0 +1,416 @@ +Git 2.32 Release Notes +====================== + +Backward compatibility notes +---------------------------- + + * ".gitattributes", ".gitignore", and ".mailmap" files that are + symbolic links are ignored. + + * "git apply --3way" used to first attempt a straight application, + and only fell back to the 3-way merge algorithm when the stright + application failed. Starting with this version, the command will + first try the 3-way merge algorithm and only when it fails (either + resulting with conflict or the base versions of blobs are missing), + falls back to the usual patch application. + + +Updates since v2.31 +------------------- + +UI, Workflows & Features + + * It does not make sense to make ".gitattributes", ".gitignore" and + ".mailmap" symlinks, as they are supposed to be usable from the + object store (think: bare repositories where HEAD:.mailmap etc. are + used). When these files are symbolic links, we used to read the + contents of the files pointed by them by mistake, which has been + corrected. + + * "git stash show" learned to optionally show untracked part of the + stash. + + * "git log --format='...'" learned "%(describe)" placeholder. + + * "git repack" so far has been only capable of repacking everything + under the sun into a single pack (or split by size). A cleverer + strategy to reduce the cost of repacking a repository has been + introduced. + + * The http codepath learned to let the credential layer to cache the + password used to unlock a certificate that has successfully been + used. + + * "git commit --fixup=<commit>", which was to tweak the changes made + to the contents while keeping the original log message intact, + learned "--fixup=(amend|reword):<commit>", that can be used to + tweak both the message and the contents, and only the message, + respectively. + + * "git send-email" learned to honor the core.hooksPath configuration. + + * "git format-patch -v<n>" learned to allow a reroll count that is + not an integer. + + * "git commit" learned "--trailer <key>[=<value>]" option; together + with the interpret-trailers command, this will make it easier to + support custom trailers. + + * "git clone --reject-shallow" option fails the clone as soon as we + notice that we are cloning from a shallow repository. + + * A configuration variable has been added to force tips of certain + refs to be given a reachability bitmap. + + * "gitweb" learned "e-mail privacy" feature to redact strings that + look like e-mail addresses on various pages. + + * "git apply --3way" has always been "to fall back to 3-way merge + only when straight application fails". Swap the order of falling + back so that 3-way is always attempted first (only when the option + is given, of course) and then straight patch application is used as + a fallback when it fails. + + * "git apply" now takes "--3way" and "--cached" at the same time, and + work and record results only in the index. + + * The command line completion (in contrib/) has learned that + CHERRY_PICK_HEAD is a possible pseudo-ref. + + * Userdiff patterns for "Scheme" has been added. + + * "git log" learned "--diff-merges=<style>" option, with an + associated configuration variable log.diffMerges. + + * "git log --format=..." placeholders learned %ah/%ch placeholders to + request the --date=human output. + + * Replace GIT_CONFIG_NOSYSTEM mechanism to decline from reading the + system-wide configuration file with GIT_CONFIG_SYSTEM that lets + users specify from which file to read the system-wide configuration + (setting it to an empty file would essentially be the same as + setting NOSYSTEM), and introduce GIT_CONFIG_GLOBAL to override the + per-user configuration in $HOME/.gitconfig. + + * "git add" and "git rm" learned not to touch those paths that are + outside of sparse checkout. + + * "git rev-list" learns the "--filter=object:type=<type>" option, + which can be used to exclude objects of the given kind from the + packfile generated by pack-objects. + + * The command line completion (in contrib/) for "git stash" has been + updated. + + * "git subtree" updates. + + * It is now documented that "format-patch" skips merges. + + * Options to "git pack-objects" that take numeric values like + --window and --depth should not accept negative values; the input + validation has been tightened. + + * The way the command line specified by the trailer.<token>.command + configuration variable receives the end-user supplied value was + both error prone and misleading. An alternative to achieve the + same goal in a safer and more intuitive way has been added, as + the trailer.<token>.cmd configuration variable, to replace it. + + * "git add -i --dry-run" does not dry-run, which was surprising. The + combination of options has taught to error out. + + * "git push" learns to discover common ancestor with the receiving + end over protocol v2. This will hopefully make "git push" as + efficient as "git fetch" in avoiding objects from getting + transferred unnecessarily. + + * "git mailinfo" (hence "git am") learned the "--quoted-cr" option to + control how lines ending with CRLF wrapped in base64 or qp are + handled. + + +Performance, Internal Implementation, Development Support etc. + + * Rename detection rework continues. + + * GIT_TEST_FAIL_PREREQS is a mechanism to skip test pieces with + prerequisites to catch broken tests that depend on the side effects + of optional pieces, but did not work at all when negative + prerequisites were involved. + (merge 27d578d904 jk/fail-prereq-testfix later to maint). + + * "git diff-index" codepath has been taught to trust fsmonitor status + to reduce number of lstat() calls. + (merge 7e5aa13d2c nk/diff-index-fsmonitor later to maint). + + * Reorganize Makefile to allow building git.o and other essential + objects without extra stuff needed only for testing. + + * Preparatory API changes for parallel checkout. + + * A simple IPC interface gets introduced to build services like + fsmonitor on top. + + * Fsck API clean-up. + + * SECURITY.md that is facing individual contributors and end users + has been introduced. Also a procedure to follow when preparing + embargoed releases has been spelled out. + (merge 09420b7648 js/security-md later to maint). + + * Optimize "rev-list --use-bitmap-index --objects" corner case that + uses negative tags as the stopping points. + + * CMake update for vsbuild. + + * An on-disk reverse-index to map the in-pack location of an object + back to its object name across multiple packfiles is introduced. + + * Generate [ec]tags under $(QUIET_GEN). + + * Clean-up codepaths that implements "git send-email --validate" + option and improves the message from it. + + * The last remnant of gettext-poison has been removed. + + * The test framework has been taught to optionally turn the default + merge strategy to "ort" throughout the system where we use + three-way merges internally, like cherry-pick, rebase etc., + primarily to enhance its test coverage (the strategy has been + available as an explicit "-s ort" choice). + + * A bit of code clean-up and a lot of test clean-up around userdiff + area. + + * Handling of "promisor packs" that allows certain objects to be + missing and lazily retrievable has been optimized (a bit). + + * When packet_write() fails, we gave an extra error message + unnecessarily, which has been corrected. + + * The checkout machinery has been taught to perform the actual + write-out of the files in parallel when able. + + * Show errno in the trace output in the error codepath that calls + read_raw_ref method. + + * Effort to make the command line completion (in contrib/) safe with + "set -u" continues. + + * Tweak a few tests for "log --format=..." that show timestamps in + various formats. + + * The reflog expiry machinery has been taught to emit trace events. + + * Over-the-wire protocol learns a new request type to ask for object + sizes given a list of object names. + + +Fixes since v2.31 +----------------- + + * The fsmonitor interface read from its input without making sure + there is something to read from. This bug is new in 2.31 + timeframe. + + * The data structure used by fsmonitor interface was not properly + duplicated during an in-core merge, leading to use-after-free etc. + + * "git bisect" reimplemented more in C during 2.30 timeframe did not + take an annotated tag as a good/bad endpoint well. This regression + has been corrected. + + * Fix macros that can silently inject unintended null-statements. + + * CALLOC_ARRAY() macro replaces many uses of xcalloc(). + + * Update insn in Makefile comments to run fuzz-all target. + + * Fix a corner case bug in "git mv" on case insensitive systems, + which was introduced in 2.29 timeframe. + + * We had a code to diagnose and die cleanly when a required + clean/smudge filter is missing, but an assert before that + unnecessarily fired, hiding the end-user facing die() message. + (merge 6fab35f748 mt/cleanly-die-upon-missing-required-filter later to maint). + + * Update C code that sets a few configuration variables when a remote + is configured so that it spells configuration variable names in the + canonical camelCase. + (merge 0f1da600e6 ab/remote-write-config-in-camel-case later to maint). + + * A new configuration variable has been introduced to allow choosing + which version of the generation number gets used in the + commit-graph file. + (merge 702110aac6 ds/commit-graph-generation-config later to maint). + + * Perf test update to work better in secondary worktrees. + (merge 36e834abc1 jk/perf-in-worktrees later to maint). + + * Updates to memory allocation code around the use of pcre2 library. + (merge c1760352e0 ab/grep-pcre2-allocfix later to maint). + + * "git -c core.bare=false clone --bare ..." would have segfaulted, + which has been corrected. + (merge 75555676ad bc/clone-bare-with-conflicting-config later to maint). + + * When "git checkout" removes a path that does not exist in the + commit it is checking out, it wasn't careful enough not to follow + symbolic links, which has been corrected. + (merge fab78a0c3d mt/checkout-remove-nofollow later to maint). + + * A few option description strings started with capital letters, + which were corrected. + (merge 5ee90326dc cc/downcase-opt-help later to maint). + + * Plug or annotate remaining leaks that trigger while running the + very basic set of tests. + (merge 68ffe095a2 ah/plugleaks later to maint). + + * The hashwrite() API uses a buffering mechanism to avoid calling + write(2) too frequently. This logic has been refactored to be + easier to understand. + (merge ddaf1f62e3 ds/clarify-hashwrite later to maint). + + * "git cherry-pick/revert" with or without "--[no-]edit" did not spawn + the editor as expected (e.g. "revert --no-edit" after a conflict + still asked to edit the message), which has been corrected. + (merge 39edfd5cbc en/sequencer-edit-upon-conflict-fix later to maint). + + * "git daemon" has been tightened against systems that take backslash + as directory separator. + (merge 9a7f1ce8b7 rs/daemon-sanitize-dir-sep later to maint). + + * A NULL-dereference bug has been corrected in an error codepath in + "git for-each-ref", "git branch --list" etc. + (merge c685450880 jk/ref-filter-segfault-fix later to maint). + + * Streamline the codepath to fix the UTF-8 encoding issues in the + argv[] and the prefix on macOS. + (merge c7d0e61016 tb/precompose-prefix-simplify later to maint). + + * The command-line completion script (in contrib/) had a couple of + references that would have given a warning under the "-u" (nounset) + option. + (merge c5c0548d79 vs/completion-with-set-u later to maint). + + * When "git pack-objects" makes a literal copy of a part of existing + packfile using the reachability bitmaps, its update to the progress + meter was broken. + (merge 8e118e8490 jk/pack-objects-bitmap-progress-fix later to maint). + + * The dependencies for config-list.h and command-list.h were broken + when the former was split out of the latter, which has been + corrected. + (merge 56550ea718 sg/bugreport-fixes later to maint). + + * "git push --quiet --set-upstream" was not quiet when setting the + upstream branch configuration, which has been corrected. + (merge f3cce896a8 ow/push-quiet-set-upstream later to maint). + + * The prefetch task in "git maintenance" assumed that "git fetch" + from any remote would fetch all its local branches, which would + fetch too much if the user is interested in only a subset of + branches there. + (merge 32f67888d8 ds/maintenance-prefetch-fix later to maint). + + * Clarify that pathnames recorded in Git trees are most often (but + not necessarily) encoded in UTF-8. + (merge 9364bf465d ab/pathname-encoding-doc later to maint). + + * "git --config-env var=val cmd" weren't accepted (only + --config-env=var=val was). + (merge c331551ccf ps/config-env-option-with-separate-value later to maint). + + * When the reachability bitmap is in effect, the "do not lose + recently created objects and those that are reachable from them" + safety to protect us from races were disabled by mistake, which has + been corrected. + (merge 2ba582ba4c jk/prune-with-bitmap-fix later to maint). + + * Cygwin pathname handling fix. + (merge bccc37fdc7 ad/cygwin-no-backslashes-in-paths later to maint). + + * "git rebase --[no-]reschedule-failed-exec" did not work well with + its configuration variable, which has been corrected. + (merge e5b32bffd1 ab/rebase-no-reschedule-failed-exec later to maint). + + * Portability fix for command line completion script (in contrib/). + (merge f2acf763e2 si/zsh-complete-comment-fix later to maint). + + * "git repack -A -d" in a partial clone unnecessarily loosened + objects in promisor pack. + + * "git bisect skip" when custom words are used for new/old did not + work, which has been corrected. + + * A few variants of informational message "Already up-to-date" has + been rephrased. + (merge ad9322da03 js/merge-already-up-to-date-message-reword later to maint). + + * "git submodule update --quiet" did not propagate the quiet option + down to underlying "git fetch", which has been corrected. + (merge 62af4bdd42 nc/submodule-update-quiet later to maint). + + * Document that our test can use "local" keyword. + (merge a84fd3bcc6 jc/test-allows-local later to maint). + + * The word-diff mode has been taught to work better with a word + regexp that can match an empty string. + (merge 0324e8fc6b pw/word-diff-zero-width-matches later to maint). + + * "git p4" learned to find branch points more efficiently. + (merge 6b79818bfb jk/p4-locate-branch-point-optim later to maint). + + * When "git update-ref -d" removes a ref that is packed, it left + empty directories under $GIT_DIR/refs/ for + (merge 5f03e5126d wc/packed-ref-removal-cleanup later to maint). + + * "git clean" and "git ls-files -i" had confusion around working on + or showing ignored paths inside an ignored directory, which has + been corrected. + (merge b548f0f156 en/dir-traversal later to maint). + + * The handling of "%(push)" formatting element of "for-each-ref" and + friends was broken when the same codepath started handling + "%(push:<what>)", which has been corrected. + (merge 1e1c4c5eac zh/ref-filter-push-remote-fix later to maint). + + * The bash prompt script (in contrib/) did not work under "set -u". + (merge 5c0cbdb107 en/prompt-under-set-u later to maint). + + * The "chainlint" feature in the test framework is a handy way to + catch common mistakes in writing new tests, but tends to get + expensive. An knob to selectively disable it has been introduced + to help running tests that the developer has not modified. + (merge 2d86a96220 jk/test-chainlint-softer later to maint). + + * The "rev-parse" command did not diagnose the lack of argument to + "--path-format" option, which was introduced in v2.31 era, which + has been corrected. + (merge 99fc555188 wm/rev-parse-path-format-wo-arg later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge f451960708 dl/cat-file-doc-cleanup later to maint). + (merge 12604a8d0c sv/t9801-test-path-is-file-cleanup later to maint). + (merge ea7e63921c jr/doc-ignore-typofix later to maint). + (merge 23c781f173 ps/update-ref-trans-hook-doc later to maint). + (merge 42efa1231a jk/filter-branch-sha256 later to maint). + (merge 4c8e3dca6e tb/push-simple-uses-branch-merge-config later to maint). + (merge 6534d436a2 bs/asciidoctor-installation-hints later to maint). + (merge 47957485b3 ab/read-tree later to maint). + (merge 2be927f3d1 ab/diff-no-index-tests later to maint). + (merge 76593c09bb ab/detox-gettext-tests later to maint). + (merge 28e29ee38b jc/doc-format-patch-clarify later to maint). + (merge fc12b6fdde fm/user-manual-use-preface later to maint). + (merge dba94e3a85 cc/test-helper-bloom-usage-fix later to maint). + (merge 61a7660516 hn/reftable-tables-doc-update later to maint). + (merge 81ed96a9b2 jt/fetch-pack-request-fix later to maint). + (merge 151b6c2dd7 jc/doc-do-not-capitalize-clarification later to maint). + (merge 9160068ac6 js/access-nul-emulation-on-windows later to maint). + (merge 7a14acdbe6 po/diff-patch-doc later to maint). + (merge f91371b948 pw/patience-diff-clean-up later to maint). + (merge 3a7f0908b6 mt/clean-clean later to maint). + (merge d4e2d15a8b ab/streaming-simplify later to maint). + (merge 0e59f7ad67 ah/merge-ort-i18n later to maint). + (merge e6f68f62e0 ls/typofix later to maint). diff --git a/Documentation/RelNotes/2.33.0.txt b/Documentation/RelNotes/2.33.0.txt new file mode 100644 index 0000000000..893c18bfdd --- /dev/null +++ b/Documentation/RelNotes/2.33.0.txt @@ -0,0 +1,279 @@ +Git 2.33 Release Notes +====================== + +Updates since Git 2.32 +---------------------- + +UI, Workflows & Features + + * "git send-email" learned the "--sendmail-cmd" command line option + and the "sendemail.sendmailCmd" configuration variable, which is a + more sensible approach than the current way of repurposing the + "smtp-server" that is meant to name the server to instead name the + command to talk to the server. + + * The userdiff pattern for C# learned the token "record". + + * "git rev-list" learns to omit the "commit <object-name>" header + lines from the output with the `--no-commit-header` option. + + * "git worktree add --lock" learned to record why the worktree is + locked with a custom message. + + +Performance, Internal Implementation, Development Support etc. + + * The code to handle the "--format" option in "for-each-ref" and + friends made too many string comparisons on %(atom)s used in the + format string, which has been corrected by converting them into + enum when the format string is parsed. + + * Use the hashfile API in the codepath that writes the index file to + reduce code duplication. + + * Repeated rename detections in a sequence of mergy operations have + been optimized out for the 'ort' merge strategy. + + * Preliminary clean-up of tests before the main reftable changes + hits the codebase. + + * The backend for "diff -G/-S" has been updated to use pcre2 engine + when available. + + * Use ".DELETE_ON_ERROR" pseudo target to simplify our Makefile. + + * Code cleanup around struct_type_init() functions. + + * "git send-email" optimization. + + * GitHub Actions / CI update. + (merge 0dc787a9f2 js/ci-windows-update later to maint). + + * Object accesses in repositories with many alternate object store + have been optimized. + + * "git log" has been optimized not to waste cycles to load ref + decoration data that may not be needed. + + * Many "printf"-like helper functions we have have been annotated + with __attribute__() to catch placeholder/parameter mismatches. + + * Tests that cover protocol bits have been updated and helpers + used there have been consolidated. + + * The CI gained a new job to run "make sparse" check. + + * "git status" codepath learned to work with sparsely populated index + without hydrating it fully. + + * A guideline for gender neutral documentation has been added. + + * Documentation on "git diff -l<n>" and diff.renameLimit have been + updated, and the defaults for these limits have been raised. + + * The completion support used to offer alternate spelling of options + that exist only for compatibility, which has been corrected. + + * "TEST_OUTPUT_DIRECTORY=there make test" failed to work, which has + been corrected. + + * "git bundle" gained more test coverage. + + * "git read-tree" had a codepath where blobs are fetched one-by-one + from the promisor remote, which has been corrected to fetch in bulk. + + * Rewrite of "git submodule" in C continues. + + * "git checkout" and "git commit" learn to work without unnecessarily + expanding sparse indexes. + + +Fixes since v2.32 +----------------- + + * We historically rejected a very short string as an author name + while accepting a patch e-mail, which has been loosened. + (merge 72ee47ceeb ef/mailinfo-short-name later to maint). + + * The parallel checkout codepath did not initialize object ID field + used to talk to the worker processes in a futureproof way. + + * Rewrite code that triggers undefined behaviour warning. + (merge aafa5df0df jn/size-t-casted-to-off-t-fix later to maint). + + * The description of "fast-forward" in the glossary has been updated. + (merge e22f2daed0 ry/clarify-fast-forward-in-glossary later to maint). + + * Recent "git clone" left a temporary directory behind when the + transport layer returned an failure. + (merge 6aacb7d861 jk/clone-clean-upon-transport-error later to maint). + + * "git fetch" over protocol v2 left its side of the socket open after + it finished speaking, which unnecessarily wasted the resource on + the other side. + (merge ae1a7eefff jk/fetch-pack-v2-half-close-early later to maint). + + * The command line completion (in contrib/) learned that "git diff" + takes the "--anchored" option. + (merge d1e7c2cac9 tb/complete-diff-anchored later to maint). + + * "git-svn" tests assumed that "locale -a", which is used to pick an + available UTF-8 locale, is available everywhere. A knob has been + introduced to allow testers to specify a suitable locale to use. + (merge 482c962de4 dd/svn-test-wo-locale-a later to maint). + + * Update "git subtree" to work better on Windows. + (merge 77f37de39f js/subtree-on-windows-fix later to maint). + + * Remove multimail from contrib/ + (merge f74d11471f js/no-more-multimail later to maint). + + * Make the codebase MSAN clean. + (merge 4dbc55e87d ah/uninitialized-reads-fix later to maint). + + * Work around inefficient glob substitution in older versions of bash + by rewriting parts of a test. + (merge eb87c6f559 jx/t6020-with-older-bash later to maint). + + * Avoid duplicated work while building reachability bitmaps. + (merge aa9ad6fee5 jk/bitmap-tree-optim later to maint). + + * We broke "GIT_SKIP_TESTS=t?000" to skip certain tests in recent + update, which got fixed. + + * The side-band demultiplexer that is used to display progress output + from the remote end did not clear the line properly when the end of + line hits at a packet boundary, which has been corrected. + + * Some test scripts assumed that readlink(1) was universally + installed and available, which is not the case. + (merge 7c0afdf23c jk/test-without-readlink-1 later to maint). + + * Recent update to completion script (in contrib/) broke those who + use the __git_complete helper to define completion to their custom + command. + (merge cea232194d fw/complete-cmd-idx-fix later to maint). + + * Output from some of our tests were affected by the width of the + terminal that they were run in, which has been corrected by + exporting a fixed value in the COLUMNS environment. + (merge c49a177bec ab/fix-columns-to-80-during-tests later to maint). + + * On Windows, mergetool has been taught to find kdiff3.exe just like + it finds winmerge.exe. + (merge 47eb4c6890 ms/mergetools-kdiff3-on-windows later to maint). + + * When we cannot figure out how wide the terminal is, we use a + fallback value of 80 ourselves (which cannot be avoided), but when + we run the pager, we export it in COLUMNS, which forces the pager + to use the hardcoded value, even when the pager is perfectly + capable to figure it out itself. Stop exporting COLUMNS when we + fall back on the hardcoded default value for our own use. + (merge 9b6e2c8b98 js/stop-exporting-bogus-columns later to maint). + + * "git cat-file --batch-all-objects"" misbehaved when "--batch" is in + use and did not ask for certain object traits. + (merge ee02ac6164 zh/cat-file-batch-fix later to maint). + + * Some code and doc clarification around "git push". + + * The "union" conflict resultion variant misbehaved when used with + binary merge driver. + (merge 382b601acd jk/union-merge-binary later to maint). + + * Prevent "git p4" from failing to submit changes to binary file. + (merge 54662d5958 dc/p4-binary-submit-fix later to maint). + + * "git grep --and -e foo" ought to have been diagnosed as an error + but instead segfaulted, which has been corrected. + (merge fe7fe62d8d rs/grep-parser-fix later to maint). + + * The merge code had funny interactions between content based rename + detection and directory rename detection. + (merge 3585d0ea23 en/merge-dir-rename-corner-case-fix later to maint). + + * When rebuilding the multi-pack index file reusing an existing one, + we used to blindly trust the existing file and ended up carrying + corrupted data into the updated file, which has been corrected. + (merge f89ecf7988 tb/midx-use-checksum later to maint). + + * Update the location of system-side configuration file on Windows. + (merge e355307692 js/gfw-system-config-loc-fix later to maint). + + * Code recently added to support common ancestry negotiation during + "git push" did not sanity check its arguments carefully enough. + (merge eff40457a4 ab/fetch-negotiate-segv-fix later to maint). + + * Update the documentation not to assume users are of certain gender + and adds to guidelines to do so. + (merge 46a237f42f ds/gender-neutral-doc later to maint). + + * "git commit --allow-empty-message" won't abort the operation upon + an empty message, but the hint shown in the editor said otherwise. + (merge 6f70f00b4f hj/commit-allow-empty-message later to maint). + + * The code that gives an error message in "git multi-pack-index" when + no subcommand is given tried to print a NULL pointer as a strong, + which has been corrected. + (merge 88617d11f9 tb/reverse-midx later to maint). + + * CI update. + (merge a066a90db6 js/ci-check-whitespace-updates later to maint). + + * Documentation fix for "git pull --rebase=no". + (merge d3236becec fc/pull-no-rebase-merges-theirs-into-ours later to maint). + + * A race between repacking and using pack bitmaps has been corrected. + (merge dc1daacdcc jk/check-pack-valid-before-opening-bitmap later to maint). + + * The local changes stashed by "git merge --autostash" were lost when + the merge failed in certain ways, which has been corrected. + + * Windows rmdir() equivalent behaves differently from POSIX ones in + that when used on a symbolic link that points at a directory, the + target directory gets removed, which has been corrected. + (merge 3e7d4888e5 tb/mingw-rmdir-symlink-to-directory later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge bfe35a6165 ah/doc-describe later to maint). + (merge f302c1e4aa jc/clarify-revision-range later to maint). + (merge 3127ff90ea tl/fix-packfile-uri-doc later to maint). + (merge a84216c684 jk/doc-color-pager later to maint). + (merge 4e0a64a713 ab/trace2-squelch-gcc-warning later to maint). + (merge 225f7fa847 ps/rev-list-object-type-filter later to maint). + (merge 5317dfeaed dd/honor-users-tar-in-tests later to maint). + (merge ace6d8e3d6 tk/partial-clone-repack-doc later to maint). + (merge 7ba68e0cf1 js/trace2-discard-event-docfix later to maint). + (merge 8603c419d3 fc/doc-default-to-upstream-config later to maint). + (merge 1d72b604ef jk/revision-squelch-gcc-warning later to maint). + (merge abcb66c614 ar/typofix later to maint). + (merge 9853830787 ah/graph-typofix later to maint). + (merge aac578492d ab/config-hooks-path-testfix later to maint). + (merge 98c7656a18 ar/more-typofix later to maint). + (merge 6fb9195f6c jk/doc-max-pack-size later to maint). + (merge 4184cbd635 ar/mailinfo-memcmp-to-skip-prefix later to maint). + (merge 91d2347033 ar/doc-libera-chat-in-my-first-contrib later to maint). + (merge 338abb0f04 ab/cmd-foo-should-return later to maint). + (merge 546096a5cb ab/xdiff-bug-cleanup later to maint). + (merge b7b793d1e7 ab/progress-cleanup later to maint). + (merge d94f9b8e90 ba/object-info later to maint). + (merge 52ff891c03 ar/test-code-cleanup later to maint). + (merge a0538e5c8b dd/document-log-decorate-default later to maint). + (merge ce24797d38 mr/cmake later to maint). + (merge 9eb542f2ee ab/pre-auto-gc-hook-test later to maint). + (merge 9fffc38583 bk/doc-commit-typofix later to maint). + (merge 1cf823d8f0 ks/submodule-cleanup later to maint). + (merge ebbf5d2b70 js/config-mak-windows-pcre-fix later to maint). + (merge 617480d75b hn/refs-iterator-peel-returns-boolean later to maint). + (merge 6a24cc71ed ar/submodule-helper-include-cleanup later to maint). + (merge 5632e838f8 rs/khash-alloc-cleanup later to maint). + (merge b1d87fbaf1 jk/typofix later to maint). + (merge e04170697a ab/gitignore-discovery-doc later to maint). + (merge 8232a0ff48 dl/packet-read-response-end-fix later to maint). + (merge eb448631fb dl/diff-merge-base later to maint). + (merge c510928a25 hn/refs-debug-empty-prefix later to maint). + (merge ddcb189d9d tb/bitmap-type-filter-comment-fix later to maint). + (merge 878b399734 pb/submodule-recurse-doc later to maint). + (merge 734283855f jk/config-env-doc later to maint). + (merge 482e1488a9 ab/getcwd-test later to maint). + (merge f0b922473e ar/doc-markup-fix later to maint). diff --git a/Documentation/RelNotes/2.34.0.txt b/Documentation/RelNotes/2.34.0.txt new file mode 100644 index 0000000000..cfbea4802a --- /dev/null +++ b/Documentation/RelNotes/2.34.0.txt @@ -0,0 +1,48 @@ +Git 2.34 Release Notes +====================== + +Updates since Git 2.33 +---------------------- + +UI, Workflows & Features + + * Pathname expansion (like "~username/") learned a way to specify a + location relative to Git installation (e.g. its $sharedir which is + $(prefix)/share), with "%(prefix)". + + +Performance, Internal Implementation, Development Support etc. + + * "git bisect" spawned "git show-branch" only to pretty-print the + title of the commit after checking out the next version to be + tested; this has been rewritten in C. + + * "git add" can work better with the sparse index. + + * Support for ancient versions of cURL library (pre 7.19.4) has been + dropped. + + * A handful of tests that assumed implementation details of files + backend for refs have been cleaned up. + + * trace2 logs learned to show parent process name to see in what + context Git was invoked. + + * Loading of ref tips to prepare for common ancestry negotiation in + "git fetch-pack" has been optimized by taking advantage of the + commit graph when available. + + +Fixes since v2.33 +----------------- + + * Input validation of "git pack-objects --stdin-packs" has been + corrected. + (merge 561fa03529 ab/pack-stdin-packs-fix later to maint). + + * Bugfix for common ancestor negotiation recently introduced in "git + push" code path. + (merge 82823118b9 jt/push-negotiation-fixes later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 1d9c8daef8 ab/bundle-doc later to maint). diff --git a/Documentation/RelNotes/2.4.3.txt b/Documentation/RelNotes/2.4.3.txt index 914d2c1860..422e930aa2 100644 --- a/Documentation/RelNotes/2.4.3.txt +++ b/Documentation/RelNotes/2.4.3.txt @@ -66,7 +66,7 @@ Fixes since v2.4.3 * Some time ago, "git blame" (incorrectly) lost the convert_to_git() call when synthesizing a fake "tip" commit that represents the state in the working tree, which broke folks who record the history - with LF line ending to make their project portabile across + with LF line ending to make their project portable across platforms while terminating lines in their working tree files with CRLF for their platform. diff --git a/Documentation/RelNotes/2.5.0.txt b/Documentation/RelNotes/2.5.0.txt index 87044504c5..84723f912a 100644 --- a/Documentation/RelNotes/2.5.0.txt +++ b/Documentation/RelNotes/2.5.0.txt @@ -172,7 +172,8 @@ Performance, Internal Implementation, Development Support etc. incorrect patch text to "git apply". Add tests to demonstrate this. - I have a slight suspicion that this may be $gmane/87202 coming back + I have a slight suspicion that this may be + cf. <7vtzf77wjp.fsf@gitster.siamese.dyndns.org> coming back and biting us (I seem to have said "let's run with this and see what happens" back then). diff --git a/Documentation/RelNotes/2.7.0.txt b/Documentation/RelNotes/2.7.0.txt index 563dadc57e..e3cbf3a73c 100644 --- a/Documentation/RelNotes/2.7.0.txt +++ b/Documentation/RelNotes/2.7.0.txt @@ -40,7 +40,7 @@ UI, Workflows & Features * "git interpret-trailers" can now run outside of a Git repository. - * "git p4" learned to reencode the pathname it uses to communicate + * "git p4" learned to re-encode the pathname it uses to communicate with the p4 depot with a new option. * Give progress meter to "git filter-branch". diff --git a/Documentation/RelNotes/2.7.1.txt b/Documentation/RelNotes/2.7.1.txt index 6553d69e33..6323feaf64 100644 --- a/Documentation/RelNotes/2.7.1.txt +++ b/Documentation/RelNotes/2.7.1.txt @@ -10,7 +10,7 @@ Fixes since v2.7 setting GIT_WORK_TREE environment themselves. * The "exclude_list" structure has the usual "alloc, nr" pair of - fields to be used by ALLOC_GROW(), but clear_exclude_list() forgot + fields to be used by ALLOC_GROW(), but clear_pattern_list() forgot to reset 'alloc' to 0 when it cleared 'nr' to discard the managed array. diff --git a/Documentation/RelNotes/2.7.3.txt b/Documentation/RelNotes/2.7.3.txt index 6adf038915..f618d71efd 100644 --- a/Documentation/RelNotes/2.7.3.txt +++ b/Documentation/RelNotes/2.7.3.txt @@ -20,7 +20,7 @@ Fixes since v2.7.2 tests. * "git show 'HEAD:Foo[BAR]Baz'" did not interpret the argument as a - rev, i.e. the object named by the the pathname with wildcard + rev, i.e. the object named by the pathname with wildcard characters in a tree object. * "git rev-parse --git-common-dir" used in the worktree feature diff --git a/Documentation/RelNotes/2.8.0.txt b/Documentation/RelNotes/2.8.0.txt index 25079710fa..38453281b8 100644 --- a/Documentation/RelNotes/2.8.0.txt +++ b/Documentation/RelNotes/2.8.0.txt @@ -189,7 +189,7 @@ Performance, Internal Implementation, Development Support etc. * Some calls to strcpy(3) triggers a false warning from static analyzers that are less intelligent than humans, and reducing the number of these false hits helps us notice real issues. A few - calls to strcpy(3) in a couple of protrams that are already safe + calls to strcpy(3) in a couple of programs that are already safe has been rewritten to avoid false warnings. * The "name_path" API was an attempt to reduce the need to construct @@ -270,7 +270,7 @@ notes for details). setting GIT_WORK_TREE environment themselves. * The "exclude_list" structure has the usual "alloc, nr" pair of - fields to be used by ALLOC_GROW(), but clear_exclude_list() forgot + fields to be used by ALLOC_GROW(), but clear_pattern_list() forgot to reset 'alloc' to 0 when it cleared 'nr' to discard the managed array. @@ -377,7 +377,7 @@ notes for details). on that order. * "git show 'HEAD:Foo[BAR]Baz'" did not interpret the argument as a - rev, i.e. the object named by the the pathname with wildcard + rev, i.e. the object named by the pathname with wildcard characters in a tree object. (merge aac4fac nd/dwim-wildcards-as-pathspecs later to maint). diff --git a/Documentation/RelNotes/2.8.3.txt b/Documentation/RelNotes/2.8.3.txt index fedd9968e5..a63825ed87 100644 --- a/Documentation/RelNotes/2.8.3.txt +++ b/Documentation/RelNotes/2.8.3.txt @@ -55,8 +55,8 @@ Fixes since v2.8.2 This is necessary to use Git on Windows shared directories, and is already enabled for the MinGW and plain Windows builds. It also has been used in Cygwin packaged versions of Git for quite a while. - See http://thread.gmane.org/gmane.comp.version-control.git/291853 - and http://thread.gmane.org/gmane.comp.version-control.git/275680. + See https://lore.kernel.org/git/20160419091055.GF2345@dinwoodie.org/ + and https://lore.kernel.org/git/20150811100527.GW14466@dinwoodie.org/. * "git replace -e" did not honour "core.editor" configuration. diff --git a/Documentation/RelNotes/2.9.0.txt b/Documentation/RelNotes/2.9.0.txt index b61d36712f..991640119a 100644 --- a/Documentation/RelNotes/2.9.0.txt +++ b/Documentation/RelNotes/2.9.0.txt @@ -368,7 +368,7 @@ notes for details). This is necessary to use Git on Windows shared directories, and is already enabled for the MinGW and plain Windows builds. It also has been used in Cygwin packaged versions of Git for quite a while. - See http://thread.gmane.org/gmane.comp.version-control.git/291853 + See https://lore.kernel.org/git/20160419091055.GF2345@dinwoodie.org/ * "merge-octopus" strategy did not ensure that the index is clean when merge begins. diff --git a/Documentation/RelNotes/2.9.3.txt b/Documentation/RelNotes/2.9.3.txt index 695b86f612..305e08062b 100644 --- a/Documentation/RelNotes/2.9.3.txt +++ b/Documentation/RelNotes/2.9.3.txt @@ -36,7 +36,7 @@ Fixes since v2.9.2 * One part of "git am" had an oddball helper function that called stuff from outside "his" as opposed to calling what we have "ours", which was not gender-neutral and also inconsistent with the rest of - the system where outside stuff is usuall called "theirs" in + the system where outside stuff is usually called "theirs" in contrast to "ours". * The test framework learned a new helper test_match_signal to diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 6d589e118c..e409022d93 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -3,8 +3,9 @@ Submitting Patches == Guidelines -Here are some guidelines for people who want to contribute their code -to this software. +Here are some guidelines for people who want to contribute their code to this +software. There is also a link:MyFirstContribution.html[step-by-step tutorial] +available which covers many of these same guidelines. [[base-branch]] === Decide what to base your work on. @@ -18,7 +19,7 @@ change is relevant to. base your work on the tip of the topic. * A new feature should be based on `master` in general. If the new - feature depends on a topic that is in `pu`, but not in `master`, + feature depends on a topic that is in `seen`, but not in `master`, base your work on the tip of that topic. * Corrections and enhancements to a topic not yet in `master` should @@ -27,7 +28,7 @@ change is relevant to. into the series. * In the exceptional case that a new feature depends on several topics - not in `master`, start working on `next` or `pu` privately and send + not in `master`, start working on `next` or `seen` privately and send out patches for discussion. Before the final merge, you may have to wait until some of the dependent topics graduate to `master`, and rebase your work. @@ -37,7 +38,7 @@ change is relevant to. these parts should be based on their trees. To find the tip of a topic branch, run `git log --first-parent -master..pu` and look for the merge commit. The second parent of this +master..seen` and look for the merge commit. The second parent of this commit is the tip of the topic branch. [[separate-commits]] @@ -73,10 +74,9 @@ the feature triggers the new behavior when it should, and to show the feature does not trigger when it shouldn't. After any code change, make sure that the entire test suite passes. -If you have an account at GitHub (and you can get one for free to work -on open source projects), you can use their Travis CI integration to -test your changes on Linux, Mac (and hopefully soon Windows). See -GitHub-Travis CI hints section for details. +Pushing to a fork of https://github.com/git/git will use their CI +integration to test your changes on Linux, Mac and Windows. See the +<<GHCI,GitHub CI>> section for details. Do not forget to update the documentation to describe the updated behavior and make sure that the resulting documentation set formats @@ -116,10 +116,13 @@ If in doubt which identifier to use, run `git log --no-merges` on the files you are modifying to see the current conventions. [[summary-section]] -It's customary to start the remainder of the first line after "area: " -with a lower-case letter. E.g. "doc: clarify...", not "doc: -Clarify...", or "githooks.txt: improve...", not "githooks.txt: -Improve...". +The title sentence after the "area:" prefix omits the full stop at the +end, and its first word is not capitalized unless there is a reason to +capitalize it other than because it is the first word in the sentence. +E.g. "doc: clarify...", not "doc: Clarify...", or "githooks.txt: +improve...", not "githooks.txt: Improve...". But "refs: HEAD is also +treated as a ref" is correct, as we spell `HEAD` in all caps even when +it appears in the middle of a sentence. [[meaningful-message]] The body should provide a meaningful commit message, which: @@ -142,21 +145,106 @@ archive, summarize the relevant points of the discussion. [[commit-reference]] If you want to reference a previous commit in the history of a stable -branch, use the format "abbreviated sha1 (subject, date)", -with the subject enclosed in a pair of double-quotes, like this: +branch, use the format "abbreviated hash (subject, date)", like this: .... - Commit f86a374 ("pack-bitmap.c: fix a memleak", 2015-03-30) + Commit f86a374 (pack-bitmap.c: fix a memleak, 2015-03-30) noticed that ... .... The "Copy commit summary" command of gitk can be used to obtain this -format, or this invocation of `git show`: +format (with the subject enclosed in a pair of double-quotes), or this +invocation of `git show`: .... - git show -s --date=short --pretty='format:%h ("%s", %ad)' <commit> + git show -s --pretty=reference <commit> .... +or, on an older version of Git without support for --pretty=reference: + +.... + git show -s --date=short --pretty='format:%h (%s, %ad)' <commit> +.... + +[[sign-off]] +=== Certify your work by adding your `Signed-off-by` trailer + +To improve tracking of who did what, we ask you to certify that you +wrote the patch or have the right to pass it on under the same license +as ours, by "signing off" your patch. Without sign-off, we cannot +accept your patches. + +If (and only if) you certify the below D-C-O: + +[[dco]] +.Developer's Certificate of Origin 1.1 +____ +By making a contribution to this project, I certify that: + +a. The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +b. The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +c. The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +d. I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +____ + +you add a "Signed-off-by" trailer to your commit, that looks like +this: + +.... + Signed-off-by: Random J Developer <random@developer.example.org> +.... + +This line can be added by Git if you run the git-commit command with +the -s option. + +Notice that you can place your own `Signed-off-by` trailer when +forwarding somebody else's patch with the above rules for +D-C-O. Indeed you are encouraged to do so. Do not forget to +place an in-body "From: " line at the beginning to properly attribute +the change to its true author (see (2) above). + +This procedure originally came from the Linux kernel project, so our +rule is quite similar to theirs, but what exactly it means to sign-off +your patch differs from project to project, so it may be different +from that of the project you are accustomed to. + +[[real-name]] +Also notice that a real name is used in the `Signed-off-by` trailer. Please +don't hide your real name. + +[[commit-trailers]] +If you like, you can put extra tags at the end: + +. `Reported-by:` is used to credit someone who found the bug that + the patch attempts to fix. +. `Acked-by:` says that the person who is more familiar with the area + the patch attempts to modify liked the patch. +. `Reviewed-by:`, unlike the other tags, can only be offered by the + reviewers themselves when they are completely satisfied with the + patch after a detailed analysis. +. `Tested-by:` is used to indicate that the person applied the patch + and found it to have the desired effect. + +You can also create your own tag or use one that's in common usage +such as "Thanks-to:", "Based-on-patch-by:", or "Mentored-by:". + [[git-tools]] === Generate your patch using Git tools out of your commits. @@ -202,7 +290,7 @@ send them as replies to either an additional "cover letter" message (see below), the first patch, or the respective preceding patch. If your log message (including your name on the -Signed-off-by line) is not writable in ASCII, make sure that +`Signed-off-by` trailer) is not writable in ASCII, make sure that you send off a message in the correct encoding. WARNING: Be wary of your MUAs word-wrap @@ -222,7 +310,7 @@ previously sent. The `git format-patch` command follows the best current practice to format the body of an e-mail message. At the beginning of the patch should come your commit message, ending with the -Signed-off-by: lines, and a line that consists of three dashes, +`Signed-off-by` trailers, and a line that consists of three dashes, followed by the diffstat information and the patch itself. If you are forwarding a patch from somebody else, optionally, at the beginning of the e-mail message just before the commit @@ -283,98 +371,23 @@ identify them), to solicit comments and reviews. :git-ml: footnote:[The mailing list: git@vger.kernel.org] After the list reached a consensus that it is a good idea to apply the -patch, re-send it with "To:" set to the maintainer{current-maintainer} and "cc:" the -list{git-ml} for inclusion. +patch, re-send it with "To:" set to the maintainer{current-maintainer} +and "cc:" the list{git-ml} for inclusion. This is especially relevant +when the maintainer did not heavily participate in the discussion and +instead left the review to trusted others. Do not forget to add trailers such as `Acked-by:`, `Reviewed-by:` and `Tested-by:` lines as necessary to credit people who helped your -patch. - -[[sign-off]] -=== Certify your work by adding your "Signed-off-by: " line - -To improve tracking of who did what, we've borrowed the -"sign-off" procedure from the Linux kernel project on patches -that are being emailed around. Although core Git is a lot -smaller project it is a good discipline to follow it. - -The sign-off is a simple line at the end of the explanation for -the patch, which certifies that you wrote it or otherwise have -the right to pass it on as an open-source patch. The rules are -pretty simple: if you can certify the below D-C-O: - -[[dco]] -.Developer's Certificate of Origin 1.1 -____ -By making a contribution to this project, I certify that: - -a. The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -b. The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -c. The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -d. I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -____ - -then you just add a line saying - -.... - Signed-off-by: Random J Developer <random@developer.example.org> -.... - -This line can be automatically added by Git if you run the git-commit -command with the -s option. - -Notice that you can place your own Signed-off-by: line when -forwarding somebody else's patch with the above rules for -D-C-O. Indeed you are encouraged to do so. Do not forget to -place an in-body "From: " line at the beginning to properly attribute -the change to its true author (see (2) above). - -[[real-name]] -Also notice that a real name is used in the Signed-off-by: line. Please -don't hide your real name. - -[[commit-trailers]] -If you like, you can put extra tags at the end: - -. `Reported-by:` is used to credit someone who found the bug that - the patch attempts to fix. -. `Acked-by:` says that the person who is more familiar with the area - the patch attempts to modify liked the patch. -. `Reviewed-by:`, unlike the other tags, can only be offered by the - reviewer and means that she is completely satisfied that the patch - is ready for application. It is usually offered only after a - detailed review. -. `Tested-by:` is used to indicate that the person applied the patch - and found it to have the desired effect. - -You can also create your own tag or use one that's in common usage -such as "Thanks-to:", "Based-on-patch-by:", or "Mentored-by:". +patch, and "cc:" them when sending such a final version for inclusion. == Subsystems with dedicated maintainers Some parts of the system have dedicated maintainers with their own repositories. -- `git-gui/` comes from git-gui project, maintained by Pat Thoyts: +- `git-gui/` comes from git-gui project, maintained by Pratyush Yadav: - git://repo.or.cz/git-gui.git + https://github.com/prati0100/git-gui.git - `gitk-git/` comes from Paul Mackerras's gitk project: @@ -417,7 +430,7 @@ help you find out who they are. and cooked further and eventually graduates to `master`. In any time between the (2)-(3) cycle, the maintainer may pick it up -from the list and queue it to `pu`, in order to make it easier for +from the list and queue it to `seen`, in order to make it easier for people play with it without having to pick up and apply the patch to their trees themselves. @@ -428,20 +441,19 @@ their trees themselves. master. `git pull --rebase` will automatically skip already-applied patches, and will let you know. This works only if you rebase on top of the branch in which your patch has been merged (i.e. it will not - tell you if your patch is merged in pu if you rebase on top of + tell you if your patch is merged in `seen` if you rebase on top of master). * Read the Git mailing list, the maintainer regularly posts messages entitled "What's cooking in git.git" and "What's in git.git" giving the status of various proposed changes. -[[travis]] -== GitHub-Travis CI hints +== GitHub CI[[GHCI]]] -With an account at GitHub (you can get one for free to work on open -source projects), you can use Travis CI to test your changes on Linux, -Mac (and hopefully soon Windows). You can find a successful example -test build here: https://travis-ci.org/git/git/builds/120473209 +With an account at GitHub, you can use GitHub CI to test your changes +on Linux, Mac and Windows. See +https://github.com/git/git/actions/workflows/main.yml for examples of +recent CI runs. Follow these steps for the initial setup: @@ -449,31 +461,18 @@ Follow these steps for the initial setup: You can find detailed instructions how to fork here: https://help.github.com/articles/fork-a-repo/ -. Open the Travis CI website: https://travis-ci.org - -. Press the "Sign in with GitHub" button. - -. Grant Travis CI permissions to access your GitHub account. - You can find more information about the required permissions here: - https://docs.travis-ci.com/user/github-oauth-scopes - -. Open your Travis CI profile page: https://travis-ci.org/profile - -. Enable Travis CI builds for your Git fork. - -After the initial setup, Travis CI will run whenever you push new changes +After the initial setup, CI will run whenever you push new changes to your fork of Git on GitHub. You can monitor the test state of all your -branches here: https://travis-ci.org/__<Your GitHub handle>__/git/branches +branches here: https://github.com/<Your GitHub handle>/git/actions/workflows/main.yml If a branch did not pass all test cases then it is marked with a red -cross. In that case you can click on the failing Travis CI job and -scroll all the way down in the log. Find the line "<-- Click here to see -detailed test output!" and click on the triangle next to the log line -number to expand the detailed test output. Here is such a failing -example: https://travis-ci.org/git/git/jobs/122676187 - -Fix the problem and push your fix to your Git fork. This will trigger -a new Travis CI build to ensure all tests pass. +cross. In that case you can click on the failing job and navigate to +"ci/run-build-and-tests.sh" and/or "ci/print-test-failures.sh". You +can also download "Artifacts" which are tarred (or zipped) archives +with test data relevant for debugging. + +Then fix the problem and push your fix to your GitHub fork. This will +trigger a new CI build to ensure all tests pass. [[mua]] == MUA specific hints diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf index 2c16c536ba..3e4c13971b 100644 --- a/Documentation/asciidoc.conf +++ b/Documentation/asciidoc.conf @@ -31,24 +31,6 @@ ifdef::backend-docbook[] endif::backend-docbook[] ifdef::backend-docbook[] -ifndef::git-asciidoc-no-roff[] -# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. -# v1.72 breaks with this because it replaces dots not in roff requests. -[listingblock] -<example><title>{title}</title> -<literallayout class="monospaced"> -ifdef::doctype-manpage[] - .ft C -endif::doctype-manpage[] -| -ifdef::doctype-manpage[] - .ft -endif::doctype-manpage[] -</literallayout> -{title#}</example> -endif::git-asciidoc-no-roff[] - -ifdef::git-asciidoc-no-roff[] ifdef::doctype-manpage[] # The following two small workarounds insert a simple paragraph after screen [listingblock] @@ -67,7 +49,6 @@ ifdef::doctype-manpage[] {title#}</para></formalpara> {title%}<simpara></simpara> endif::doctype-manpage[] -endif::git-asciidoc-no-roff[] endif::backend-docbook[] ifdef::doctype-manpage[] @@ -78,9 +59,9 @@ template::[header-declarations] <refmeta> <refentrytitle>{mantitle}</refentrytitle> <manvolnum>{manvolnum}</manvolnum> -<refmiscinfo class="source">Git</refmiscinfo> -<refmiscinfo class="version">{git_version}</refmiscinfo> -<refmiscinfo class="manual">Git Manual</refmiscinfo> +<refmiscinfo class="source">{mansource}</refmiscinfo> +<refmiscinfo class="version">{manversion}</refmiscinfo> +<refmiscinfo class="manual">{manmanual}</refmiscinfo> </refmeta> <refnamediv> <refname>{manname}</refname> diff --git a/Documentation/asciidoctor-extensions.rb b/Documentation/asciidoctor-extensions.rb index 0089e0cfb8..d906a00803 100644 --- a/Documentation/asciidoctor-extensions.rb +++ b/Documentation/asciidoctor-extensions.rb @@ -9,8 +9,11 @@ module Git named :chrome def process(parent, target, attrs) - if parent.document.basebackend? 'html' - prefix = parent.document.attr('git-relative-html-prefix') + prefix = parent.document.attr('git-relative-html-prefix') + if parent.document.doctype == 'book' + "<ulink url=\"#{prefix}#{target}.html\">" \ + "#{target}(#{attrs[1]})</ulink>" + elsif parent.document.basebackend? 'html' %(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>) elsif parent.document.basebackend? 'docbook' "<citerefentry>\n" \ @@ -20,9 +23,26 @@ module Git end end end + + class DocumentPostProcessor < Asciidoctor::Extensions::Postprocessor + def process document, output + if document.basebackend? 'docbook' + mansource = document.attributes['mansource'] + manversion = document.attributes['manversion'] + manmanual = document.attributes['manmanual'] + new_tags = "" \ + "<refmiscinfo class=\"source\">#{mansource}</refmiscinfo>\n" \ + "<refmiscinfo class=\"version\">#{manversion}</refmiscinfo>\n" \ + "<refmiscinfo class=\"manual\">#{manmanual}</refmiscinfo>\n" + output = output.sub(/<\/refmeta>/, new_tags + "</refmeta>") + end + output + end + end end end Asciidoctor::Extensions.register do inline_macro Git::Documentation::LinkGitProcessor, :linkgit + postprocessor Git::Documentation::DocumentPostProcessor end diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt index dc41957afa..117f4cf806 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.txt @@ -1,6 +1,6 @@ -b:: Show blank SHA-1 for boundary commits. This can also - be controlled via the `blame.blankboundary` config option. + be controlled via the `blame.blankBoundary` config option. --root:: Do not treat root commits as boundaries. This can also be @@ -11,11 +11,12 @@ -L <start>,<end>:: -L :<funcname>:: - Annotate only the given line range. May be specified multiple times. - Overlapping ranges are allowed. + Annotate only the line range given by '<start>,<end>', + or by the function name regex '<funcname>'. + May be specified multiple times. Overlapping ranges are allowed. + -<start> and <end> are optional. ``-L <start>'' or ``-L <start>,'' spans from -<start> to end of file. ``-L ,<end>'' spans from start of file to <end>. +'<start>' and '<end>' are optional. `-L <start>` or `-L <start>,` spans from +'<start>' to end of file. `-L ,<end>` spans from start of file to '<end>'. + include::line-range-format.txt[] @@ -36,6 +37,12 @@ include::line-range-format.txt[] START. `git blame --reverse START` is taken as `git blame --reverse START..HEAD` for convenience. +--first-parent:: + Follow only the first parent commit upon seeing a merge + commit. This option can be used to determine when a line + was introduced to a particular integration branch, rather + than when it was introduced to the history overall. + -p:: --porcelain:: Show in a format designed for machine consumption. @@ -110,5 +117,24 @@ commit. And the default value is 40. If there are more than one `-C` options given, the <num> argument of the last `-C` will take effect. +--ignore-rev <rev>:: + Ignore changes made by the revision when assigning blame, as if the + change never happened. Lines that were changed or added by an ignored + commit will be blamed on the previous commit that changed that line or + nearby lines. This option may be specified multiple times to ignore + more than one revision. If the `blame.markIgnoredLines` config option + is set, then lines that were changed by an ignored commit and attributed to + another commit will be marked with a `?` in the blame output. If the + `blame.markUnblamableLines` config option is set, then those lines touched + by an ignored commit that we could not attribute to another revision are + marked with a '*'. + +--ignore-revs-file <file>:: + Ignore revisions listed in `file`, which must be in the same format as an + `fsck.skipList`. This option may be repeated, and these files will be + processed after any files specified with the `blame.ignoreRevsFile` config + option. An empty file name, `""`, will clear the list of revs from + previously processed files. + -h:: Show help message. diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 5aa73cfe45..af5da45d28 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -6,9 +6,14 @@ sub format_one { my ($out, $nameattr) = @_; my ($name, $attr) = @$nameattr; my ($state, $description); + my $mansection; $state = 0; open I, '<', "$name.txt" or die "No such file $name.txt"; while (<I>) { + if (/^git[a-z0-9-]*\(([0-9])\)$/) { + $mansection = $1; + next; + } if (/^NAME$/) { $state = 1; next; @@ -27,7 +32,7 @@ sub format_one { die "No description found in $name.txt"; } if (my ($verify_name, $text) = ($description =~ /^($name) - (.*)/)) { - print $out "linkgit:$name\[1\]::\n\t"; + print $out "linkgit:$name\[$mansection\]::\n\t"; if ($attr =~ / deprecated /) { print $out "(deprecated) "; } @@ -38,12 +43,15 @@ sub format_one { } } -while (<>) { +my ($input, @categories) = @ARGV; + +open IN, "<$input"; +while (<IN>) { last if /^### command list/; } my %cmds = (); -for (sort <>) { +for (sort <IN>) { next if /^#/; chomp; @@ -51,17 +59,10 @@ for (sort <>) { $attr = '' unless defined $attr; push @{$cmds{$cat}}, [$name, " $attr "]; } +close IN; -for my $cat (qw(ancillaryinterrogators - ancillarymanipulators - mainporcelain - plumbinginterrogators - plumbingmanipulators - synchingrepositories - foreignscminterface - purehelpers - synchelpers)) { - my $out = "cmds-$cat.txt"; +for my $out (@categories) { + my ($cat) = $out =~ /^cmds-(.*)\.txt$/; open O, '>', "$out+" or die "Cannot open output file $out+"; for (@{$cmds{$cat}}) { format_one(\*O, $_); diff --git a/Documentation/config.txt b/Documentation/config.txt index 7e2a6f61f5..0c0e6b859f 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -3,11 +3,12 @@ CONFIGURATION FILE The Git configuration file contains a number of variables that affect the Git commands' behavior. The files `.git/config` and optionally -`config.worktree` (see `extensions.worktreeConfig` below) in each -repository are used to store the configuration for that repository, and -`$HOME/.gitconfig` is used to store a per-user configuration as -fallback values for the `.git/config` file. The file `/etc/gitconfig` -can be used to store a system-wide default configuration. +`config.worktree` (see the "CONFIGURATION FILE" section of +linkgit:git-worktree[1]) in each repository are used to store the +configuration for that repository, and `$HOME/.gitconfig` is used to +store a per-user configuration as fallback values for the `.git/config` +file. The file `/etc/gitconfig` can be used to store a system-wide +default configuration. The configuration variables are used by both the Git plumbing and the porcelains. The variables are divided into sections, wherein @@ -45,7 +46,7 @@ Subsection names are case sensitive and can contain any characters except newline and the null byte. Doublequote `"` and backslash can be included by escaping them as `\"` and `\\`, respectively. Backslashes preceding other characters are dropped when reading; for example, `\t` is read as -`t` and `\0` is read as `0` Section headers cannot span multiple lines. +`t` and `\0` is read as `0`. Section headers cannot span multiple lines. Variables may belong directly to a section or to a given subsection. You can have `[section]` if you have `[section "subsection"]`, but you don't need to. @@ -63,7 +64,7 @@ The variable names are case-insensitive, allow only alphanumeric characters and `-`, and must start with an alphabetic character. A line that defines a value can be continued to the next line by -ending it with a `\`; the backquote and the end-of-line are +ending it with a `\`; the backslash and the end-of-line are stripped. Leading whitespaces after 'name =', the remainder of the line after the first comment character '#' or ';', and trailing whitespaces of the line are discarded unless they are enclosed in @@ -142,7 +143,21 @@ refer to linkgit:gitignore[5] for details. For convenience: `gitdir/i`:: This is the same as `gitdir` except that matching is done - case-insensitively (e.g. on case-insensitive file sytems) + case-insensitively (e.g. on case-insensitive file systems) + +`onbranch`:: + The data that follows the keyword `onbranch:` is taken to be a + pattern with standard globbing wildcards and two additional + ones, `**/` and `/**`, that can match multiple path components. + If we are in a worktree where the name of the branch that is + currently checked out matches the pattern, the include condition + is met. ++ +If the pattern ends with `/`, `**` will be automatically added. For +example, the pattern `foo/` becomes `foo/**`. In other words, it matches +all branches that begin with `foo/`. This is useful if your branches are +organized hierarchically and you would like to apply a configuration to +all the branches in that hierarchy. A few more notes on matching via `gitdir` and `gitdir/i`: @@ -164,47 +179,54 @@ to either specify only the realpath version, or both versions. Example ~~~~~~~ - # Core variables - [core] - ; Don't trust file modes - filemode = false - - # Our diff algorithm - [diff] - external = /usr/local/bin/diff-wrapper - renames = true - - [branch "devel"] - remote = origin - merge = refs/heads/devel - - # Proxy settings - [core] - gitProxy="ssh" for "kernel.org" - gitProxy=default-proxy ; for the rest - - [include] - path = /path/to/foo.inc ; include by absolute path - path = foo.inc ; find "foo.inc" relative to the current file - path = ~/foo.inc ; find "foo.inc" in your `$HOME` directory - - ; include if $GIT_DIR is /path/to/foo/.git - [includeIf "gitdir:/path/to/foo/.git"] - path = /path/to/foo.inc - - ; include for all repositories inside /path/to/group - [includeIf "gitdir:/path/to/group/"] - path = /path/to/foo.inc - - ; include for all repositories inside $HOME/to/group - [includeIf "gitdir:~/to/group/"] - path = /path/to/foo.inc - - ; relative paths are always relative to the including - ; file (if the condition is true); their location is not - ; affected by the condition - [includeIf "gitdir:/path/to/group/"] - path = foo.inc +---- +# Core variables +[core] + ; Don't trust file modes + filemode = false + +# Our diff algorithm +[diff] + external = /usr/local/bin/diff-wrapper + renames = true + +[branch "devel"] + remote = origin + merge = refs/heads/devel + +# Proxy settings +[core] + gitProxy="ssh" for "kernel.org" + gitProxy=default-proxy ; for the rest + +[include] + path = /path/to/foo.inc ; include by absolute path + path = foo.inc ; find "foo.inc" relative to the current file + path = ~/foo.inc ; find "foo.inc" in your `$HOME` directory + +; include if $GIT_DIR is /path/to/foo/.git +[includeIf "gitdir:/path/to/foo/.git"] + path = /path/to/foo.inc + +; include for all repositories inside /path/to/group +[includeIf "gitdir:/path/to/group/"] + path = /path/to/foo.inc + +; include for all repositories inside $HOME/to/group +[includeIf "gitdir:~/to/group/"] + path = /path/to/foo.inc + +; relative paths are always relative to the including +; file (if the condition is true); their location is not +; affected by the condition +[includeIf "gitdir:/path/to/group/"] + path = foo.inc + +; include only if we are in a worktree where foo-branch is +; currently checked out +[includeIf "onbranch:foo-branch"] + path = foo.inc +---- Values ~~~~~~ @@ -242,7 +264,9 @@ color:: + The basic colors accepted are `normal`, `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan` and `white`. The first color given is the -foreground; the second is the background. +foreground; the second is the background. All the basic colors except +`normal` have a bright variant that can be specified by prefixing the +color with `bright`, like `brightred`. + Colors may also be given as numbers between 0 and 255; these use ANSI 256-color mode (but note that not all terminals may support this). If @@ -274,6 +298,15 @@ pathname:: tilde expansion happens to such a string: `~/` is expanded to the value of `$HOME`, and `~user/` to the specified user's home directory. ++ +If a path starts with `%(prefix)/`, the remainder is interpreted as a +path relative to Git's "runtime prefix", i.e. relative to the location +where Git itself was installed. For example, `%(prefix)/bin/` refers to +the directory in which the Git executable itself lives. If Git was +compiled without runtime prefix support, the compiled-in prefix will be +subsituted instead. In the unlikely event that a literal path needs to +be specified that should _not_ be expanded, it needs to be prefixed by +`./`, like so: `./%(prefix)/bin`. Variables @@ -310,12 +343,16 @@ include::config/checkout.txt[] include::config/clean.txt[] +include::config/clone.txt[] + include::config/color.txt[] include::config/column.txt[] include::config/commit.txt[] +include::config/commitgraph.txt[] + include::config/credential.txt[] include::config/completion.txt[] @@ -324,8 +361,12 @@ include::config/diff.txt[] include::config/difftool.txt[] +include::config/extensions.txt[] + include::config/fastimport.txt[] +include::config/feature.txt[] + include::config/fetch.txt[] include::config/format.txt[] @@ -366,10 +407,14 @@ include::config/interactive.txt[] include::config/log.txt[] +include::config/lsrefs.txt[] + include::config/mailinfo.txt[] include::config/mailmap.txt[] +include::config/maintenance.txt[] + include::config/man.txt[] include::config/merge.txt[] @@ -422,6 +467,8 @@ include::config/submodule.txt[] include::config/tag.txt[] +include::config/tar.txt[] + include::config/trace2.txt[] include::config/transfer.txt[] diff --git a/Documentation/config/add.txt b/Documentation/config/add.txt index 4d753f006e..c9f748f81c 100644 --- a/Documentation/config/add.txt +++ b/Documentation/config/add.txt @@ -5,3 +5,8 @@ add.ignore-errors (deprecated):: option of linkgit:git-add[1]. `add.ignore-errors` is deprecated, as it does not follow the usual naming convention for configuration variables. + +add.interactive.useBuiltin:: + [EXPERIMENTAL] Set to `true` to use the experimental built-in + implementation of the interactive version of linkgit:git-add[1] + instead of the Perl script version. Is `false` by default. diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt index ec4f6ae658..8b2849ff7b 100644 --- a/Documentation/config/advice.txt +++ b/Documentation/config/advice.txt @@ -4,11 +4,14 @@ advice.*:: can tell Git that you do not need help by setting these to 'false': + -- + fetchShowForcedUpdates:: + Advice shown when linkgit:git-fetch[1] takes a long time + to calculate forced updates after ref updates, or to warn + that the check is disabled. pushUpdateRejected:: Set this variable to 'false' if you want to disable - 'pushNonFFCurrent', - 'pushNonFFMatching', 'pushAlreadyExists', - 'pushFetchFirst', and 'pushNeedsForce' + 'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists', + 'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate' simultaneously. pushNonFFCurrent:: Advice shown when linkgit:git-push[1] fails due to a @@ -37,12 +40,23 @@ advice.*:: we can still suggest that the user push to either refs/heads/* or refs/tags/* based on the type of the source object. + pushRefNeedsUpdate:: + Shown when linkgit:git-push[1] rejects a forced update of + a branch when its remote-tracking ref has updates that we + do not have locally. + statusAheadBehind:: + Shown when linkgit:git-status[1] computes the ahead/behind + counts for a local ref compared to its remote tracking ref, + and that calculation takes longer than expected. Will not + appear if `status.aheadBehind` is false or the option + `--no-ahead-behind` is given. statusHints:: Show directions on how to proceed from the current state in the output of linkgit:git-status[1], in the template shown when writing commit messages in linkgit:git-commit[1], and in the help message shown - by linkgit:git-checkout[1] when switching branch. + by linkgit:git-switch[1] or + linkgit:git-checkout[1] when switching branch. statusUoption:: Advise to consider using the `-u` option to linkgit:git-status[1] when the command takes more than 2 seconds to enumerate untracked @@ -57,17 +71,21 @@ advice.*:: resolveConflict:: Advice shown by various commands when conflicts prevent the operation from being performed. + sequencerInUse:: + Advice shown when a sequencer command is already in progress. implicitIdentity:: Advice on how to set your identity configuration when your information is guessed from the system username and domain name. detachedHead:: - Advice shown when you used linkgit:git-checkout[1] to - move to the detach HEAD state, to instruct how to create - a local branch after the fact. + Advice shown when you used + linkgit:git-switch[1] or linkgit:git-checkout[1] + to move to the detach HEAD state, to instruct how to + create a local branch after the fact. checkoutAmbiguousRemoteBranchName:: Advice shown when the argument to - linkgit:git-checkout[1] ambiguously resolves to a + linkgit:git-checkout[1] and linkgit:git-switch[1] + ambiguously resolves to a remote tracking branch on more than one remote in situations where an unambiguous argument would have otherwise caused a remote-tracking branch to be @@ -92,4 +110,17 @@ advice.*:: editor input from the user. nestedTag:: Advice shown if a user attempts to recursively tag a tag object. + submoduleAlternateErrorStrategyDie:: + Advice shown when a submodule.alternateErrorStrategy option + configured to "die" causes a fatal error. + addIgnoredFile:: + Advice shown if a user attempts to add an ignored file to + the index. + addEmptyPathspec:: + Advice shown if a user runs the add command without providing + the pathspec parameter. + updateSparsePath:: + Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1] + is asked to update index entries outside the current sparse + checkout. -- diff --git a/Documentation/config/blame.txt b/Documentation/config/blame.txt index 67b5c1d1e0..4d047c1790 100644 --- a/Documentation/config/blame.txt +++ b/Documentation/config/blame.txt @@ -19,3 +19,19 @@ blame.showEmail:: blame.showRoot:: Do not treat root commits as boundaries in linkgit:git-blame[1]. This option defaults to false. + +blame.ignoreRevsFile:: + Ignore revisions listed in the file, one unabbreviated object name per + line, in linkgit:git-blame[1]. Whitespace and comments beginning with + `#` are ignored. This option may be repeated multiple times. Empty + file names will reset the list of ignored revisions. This option will + be handled before the command line option `--ignore-revs-file`. + +blame.markUnblamableLines:: + Mark lines that were changed by an ignored revision that we could not + attribute to another commit with a '*' in the output of + linkgit:git-blame[1]. + +blame.markIgnoredLines:: + Mark lines that were changed by an ignored revision that we attributed to + another commit with a '?' in the output of linkgit:git-blame[1]. diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt index 8f4b3faadd..cc5f3249fc 100644 --- a/Documentation/config/branch.txt +++ b/Documentation/config/branch.txt @@ -1,5 +1,5 @@ branch.autoSetupMerge:: - Tells 'git branch' and 'git checkout' to set up new branches + Tells 'git branch', 'git switch' and 'git checkout' to set up new branches so that linkgit:git-pull[1] will appropriately merge from the starting point branch. Note that even if this option is not set, this behavior can be chosen per-branch using the `--track` @@ -11,7 +11,7 @@ branch.autoSetupMerge:: branch. This option defaults to true. branch.autoSetupRebase:: - When a new branch is created with 'git branch' or 'git checkout' + When a new branch is created with 'git branch', 'git switch' or 'git checkout' that tracks another branch, this variable tells Git to set up pull to rebase instead of merge (see "branch.<name>.rebase"). When `never`, rebase is never automatically set to true. @@ -81,15 +81,16 @@ branch.<name>.rebase:: "git pull" is run. See "pull.rebase" for doing this in a non branch-specific manner. + -When `merges`, pass the `--rebase-merges` option to 'git rebase' +When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase' so that the local merge commits are included in the rebase (see linkgit:git-rebase[1] for details). + -When `preserve` (deprecated in favor of `merges`), also pass +When `preserve` (or just 'p', deprecated in favor of `merges`), also pass `--preserve-merges` along to 'git rebase' so that locally committed merge commits will not be flattened by running 'git pull'. + -When the value is `interactive`, the rebase is run in interactive mode. +When the value is `interactive` (or just 'i'), the rebase is run in interactive +mode. + *NOTE*: this is a possibly dangerous operation; do *not* use it unless you understand the implications (see linkgit:git-rebase[1] diff --git a/Documentation/config/checkout.txt b/Documentation/config/checkout.txt index c4118fa196..bfbca90f0e 100644 --- a/Documentation/config/checkout.txt +++ b/Documentation/config/checkout.txt @@ -1,23 +1,44 @@ checkout.defaultRemote:: - When you run 'git checkout <something>' and only have one + When you run `git checkout <something>` + or `git switch <something>` and only have one remote, it may implicitly fall back on checking out and - tracking e.g. 'origin/<something>'. This stops working as soon - as you have more than one remote with a '<something>' + tracking e.g. `origin/<something>`. This stops working as soon + as you have more than one remote with a `<something>` reference. This setting allows for setting the name of a preferred remote that should always win when it comes to disambiguation. The typical use-case is to set this to `origin`. + -Currently this is used by linkgit:git-checkout[1] when 'git checkout -<something>' will checkout the '<something>' branch on another remote, -and by linkgit:git-worktree[1] when 'git worktree add' refers to a +Currently this is used by linkgit:git-switch[1] and +linkgit:git-checkout[1] when `git checkout <something>` +or `git switch <something>` +will checkout the `<something>` branch on another remote, +and by linkgit:git-worktree[1] when `git worktree add` refers to a remote branch. This setting might be used for other checkout-like commands or functionality in the future. -checkout.optimizeNewBranch:: - Optimizes the performance of "git checkout -b <new_branch>" when - using sparse-checkout. When set to true, git will not update the - repo based on the current sparse-checkout settings. This means it - will not update the skip-worktree bit in the index nor add/remove - files in the working directory to reflect the current sparse checkout - settings nor will it show the local changes. +checkout.guess:: + Provides the default value for the `--guess` or `--no-guess` + option in `git checkout` and `git switch`. See + linkgit:git-switch[1] and linkgit:git-checkout[1]. + +checkout.workers:: + The number of parallel workers to use when updating the working tree. + The default is one, i.e. sequential execution. If set to a value less + than one, Git will use as many workers as the number of logical cores + available. This setting and `checkout.thresholdForParallelism` affect + all commands that perform checkout. E.g. checkout, clone, reset, + sparse-checkout, etc. ++ +Note: parallel checkout usually delivers better performance for repositories +located on SSDs or over NFS. For repositories on spinning disks and/or machines +with a small number of cores, the default sequential checkout often performs +better. The size and compression level of a repository might also influence how +well the parallel version performs. + +checkout.thresholdForParallelism:: + When running parallel checkout with a small number of files, the cost + of subprocess spawning and inter-process communication might outweigh + the parallelization gains. This setting allows to define the minimum + number of files for which parallel checkout should be attempted. The + default is 100. diff --git a/Documentation/config/clone.txt b/Documentation/config/clone.txt new file mode 100644 index 0000000000..7bcfbd18a5 --- /dev/null +++ b/Documentation/config/clone.txt @@ -0,0 +1,8 @@ +clone.defaultRemoteName:: + The name of the remote to create when cloning a repository. Defaults to + `origin`, and can be overridden by passing the `--origin` command-line + option to linkgit:git-clone[1]. + +clone.rejectShallow:: + Reject to clone a repository if it is a shallow one, can be overridden by + passing option `--reject-shallow` in command line. See linkgit:git-clone[1] diff --git a/Documentation/config/color.txt b/Documentation/config/color.txt index 8375596c44..e05d520a86 100644 --- a/Documentation/config/color.txt +++ b/Documentation/config/color.txt @@ -14,7 +14,7 @@ color.blame.highlightRecent:: + This setting should be set to a comma-separated list of color and date settings, starting and ending with a color, the dates should be set from oldest to newest. -The metadata will be colored given the colors if the the line was introduced +The metadata will be colored given the colors if the line was introduced before the given timestamp, overwriting older timestamped colors. + Instead of an absolute timestamp relative timestamps work as well, e.g. @@ -127,8 +127,9 @@ color.interactive.<slot>:: interactive commands. color.pager:: - A boolean to enable/disable colored output when the pager is in - use (default is true). + A boolean to specify whether `auto` color modes should colorize + output going to the pager. Defaults to true; set this to false + if your pager does not understand ANSI color codes. color.push:: A boolean to enable/disable color in push errors. May be set to diff --git a/Documentation/config/commitgraph.txt b/Documentation/config/commitgraph.txt new file mode 100644 index 0000000000..30604e4a4c --- /dev/null +++ b/Documentation/config/commitgraph.txt @@ -0,0 +1,14 @@ +commitGraph.generationVersion:: + Specifies the type of generation number version to use when writing + or reading the commit-graph file. If version 1 is specified, then + the corrected commit dates will not be written or read. Defaults to + 2. + +commitGraph.maxNewFilters:: + Specifies the default value for the `--max-new-filters` option of `git + commit-graph write` (c.f., linkgit:git-commit-graph[1]). + +commitGraph.readChangedPaths:: + If true, then git will use the changed-path Bloom filters in the + commit-graph file (if it exists, and they are present). Defaults to + true. See linkgit:git-commit-graph[1] for more information. diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index 75538d27e7..c04f62a54a 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -68,6 +68,17 @@ core.fsmonitor:: avoiding unnecessary processing of files that have not changed. See the "fsmonitor-watchman" section of linkgit:githooks[5]. +core.fsmonitorHookVersion:: + Sets the version of hook that is to be used when calling fsmonitor. + There are currently versions 1 and 2. When this is not set, + version 2 will be tried first and if it fails then version 1 + will be tried. Version 1 uses a timestamp as input to determine + which files have changes since that time but some monitors + like watchman have race conditions when used with a timestamp. + Version 2 uses an opaque string so that the monitor can return + something that can be used to determine what files have changed + without race conditions. + core.trustctime:: If false, the ctime differences between the index and the working tree are ignored; useful when the inode change time @@ -86,7 +97,9 @@ core.untrackedCache:: it will automatically be removed, if set to `false`. Before setting it to `true`, you should check that mtime is working properly on your system. - See linkgit:git-update-index[1]. `keep` by default. + See linkgit:git-update-index[1]. `keep` by default, unless + `feature.manyFiles` is enabled which sets this setting to + `true` by default. core.checkStat:: When missing or is set to `default`, many fields in the stat @@ -386,7 +399,7 @@ the largest projects. You probably do not need to adjust this value. Common unit suffixes of 'k', 'm', or 'g' are supported. core.deltaBaseCacheLimit:: - Maximum number of bytes to reserve for caching base objects + Maximum number of bytes per thread to reserve for caching base objects that may be referenced by multiple deltified objects. By storing the entire decompressed base objects in a cache Git is able to avoid unpacking and decompressing frequently used base @@ -557,6 +570,12 @@ core.unsetenvvars:: Defaults to `PERL5LIB` to account for the fact that Git for Windows insists on using its own Perl interpreter. +core.restrictinheritedhandles:: + Windows-only: override whether spawned processes inherit only standard + file handles (`stdin`, `stdout` and `stderr`) or all handles. Can be + `auto`, `true` or `false`. Defaults to `auto`, which means `true` on + Windows 7 and later, and `false` on older Windows versions. + core.createObject:: You can set this to 'link', in which case a hardlink followed by a delete of the source are used to make sure that object creation @@ -577,7 +596,7 @@ the `GIT_NOTES_REF` environment variable. See linkgit:git-notes[1]. core.commitGraph:: If true, then git will read the commit-graph file (if it exists) - to parse the graph structure of commits. Defaults to false. See + to parse the graph structure of commits. Defaults to true. See linkgit:git-commit-graph[1] for more information. core.useReplaceRefs:: @@ -587,12 +606,18 @@ core.useReplaceRefs:: core.multiPackIndex:: Use the multi-pack-index file to track multiple packfiles using a - single index. See link:technical/multi-pack-index.html[the - multi-pack-index design document]. + single index. See linkgit:git-multi-pack-index[1] for more + information. Defaults to true. core.sparseCheckout:: - Enable "sparse checkout" feature. See section "Sparse checkout" in - linkgit:git-read-tree[1] for more information. + Enable "sparse checkout" feature. See linkgit:git-sparse-checkout[1] + for more information. + +core.sparseCheckoutCone:: + Enables the "cone mode" of the sparse checkout feature. When the + sparse-checkout file contains a limited set of patterns, then this + mode provides significant performance advantages. See + linkgit:git-sparse-checkout[1] for more information. core.abbrev:: Set the length object names are abbreviated to. If @@ -600,4 +625,6 @@ core.abbrev:: computed based on the approximate number of packed objects in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. + If set to "no", no abbreviation is made and the object names + are shown in their full length. The minimum length is 4. diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.txt index 60fb3189e1..512f31876e 100644 --- a/Documentation/config/credential.txt +++ b/Documentation/config/credential.txt @@ -1,9 +1,13 @@ credential.helper:: Specify an external helper to be called when a username or password credential is needed; the helper may consult external - storage to avoid prompting the user for the credentials. Note - that multiple helpers may be defined. See linkgit:gitcredentials[7] - for details. + storage to avoid prompting the user for the credentials. This is + normally the name of a credential helper with possible + arguments, but may also be an absolute path with arguments or, if + preceded by `!`, shell commands. ++ +Note that multiple helpers may be defined. See linkgit:gitcredentials[7] +for details and examples. credential.useHttpPath:: When acquiring credentials, consider the "path" component of an http @@ -24,3 +28,9 @@ credential.<url>.*:: credentialCache.ignoreSIGHUP:: Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting. + +credentialStore.lockTimeoutMS:: + The length of time, in milliseconds, for git-credential-store to retry + when trying to lock the credentials file. Value 0 means not to retry at + all; -1 means to try indefinitely. Default is 1000 (i.e., retry for + 1s). diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt index 2c4c9ba27a..32f84838ac 100644 --- a/Documentation/config/diff.txt +++ b/Documentation/config/diff.txt @@ -78,12 +78,15 @@ diff.external:: diff.ignoreSubmodules:: Sets the default value of --ignore-submodules. Note that this affects only 'git diff' Porcelain, and not lower level 'diff' - commands such as 'git diff-files'. 'git checkout' also honors + commands such as 'git diff-files'. 'git checkout' + and 'git switch' also honor this setting when reporting uncommitted changes. Setting it to 'all' disables the submodule summary normally shown by 'git commit' and 'git status' when `status.submoduleSummary` is set unless it is overridden by using the --ignore-submodules command-line option. The 'git submodule' commands are not affected by this setting. + By default this is set to untracked so that any untracked + submodules are ignored. diff.mnemonicPrefix:: If set, 'git diff' uses a prefix pair that is different from the @@ -104,6 +107,10 @@ diff.mnemonicPrefix:: diff.noprefix:: If set, 'git diff' does not show any source or destination prefix. +diff.relative:: + If set to 'true', 'git diff' does not show changes outside of the directory + and show pathnames relative to the current directory. + diff.orderFile:: File indicating how to order files within a diff. See the '-O' option to linkgit:git-diff[1] for details. @@ -111,9 +118,10 @@ diff.orderFile:: relative to the top of the working tree. diff.renameLimit:: - The number of files to consider when performing the copy/rename - detection; equivalent to the 'git diff' option `-l`. This setting - has no effect if rename detection is turned off. + The number of files to consider in the exhaustive portion of + copy/rename detection; equivalent to the 'git diff' option + `-l`. If not set, the default value is currently 1000. This + setting has no effect if rename detection is turned off. diff.renames:: Whether and how Git detects renames. If set to "false", @@ -188,7 +196,7 @@ diff.guitool:: include::../mergetools-diff.txt[] diff.indentHeuristic:: - Set this option to `true` to enable experimental heuristics + Set this option to `false` to disable the default heuristics that shift diff hunk boundaries to make patches easier to read. diff.algorithm:: diff --git a/Documentation/config/extensions.txt b/Documentation/config/extensions.txt new file mode 100644 index 0000000000..4e23d73cdc --- /dev/null +++ b/Documentation/config/extensions.txt @@ -0,0 +1,8 @@ +extensions.objectFormat:: + Specify the hash algorithm to use. The acceptable values are `sha1` and + `sha256`. If not specified, `sha1` is assumed. It is an error to specify + this key unless `core.repositoryFormatVersion` is 1. ++ +Note that this setting should only be set by linkgit:git-init[1] or +linkgit:git-clone[1]. Trying to change it after initialization will not +work and will produce hard-to-diagnose issues. diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.txt new file mode 100644 index 0000000000..cdecd04e5b --- /dev/null +++ b/Documentation/config/feature.txt @@ -0,0 +1,26 @@ +feature.*:: + The config settings that start with `feature.` modify the defaults of + a group of other config settings. These groups are created by the Git + developer community as recommended defaults and are subject to change. + In particular, new config options may be added with different defaults. + +feature.experimental:: + Enable config options that are new to Git, and are being considered for + future defaults. Config settings included here may be added or removed + with each release, including minor version updates. These settings may + have unintended interactions since they are so new. Please enable this + setting if you are interested in providing feedback on experimental + features. The new default values are: ++ +* `fetch.negotiationAlgorithm=skipping` may improve fetch negotiation times by +skipping more commits at a time, reducing the number of round trips. + +feature.manyFiles:: + Enable config options that optimize for repos with many files in the + working directory. With many files, commands such as `git status` and + `git checkout` may be slow and these new defaults improve performance: ++ +* `index.version=4` enables path-prefix compression in the index. ++ +* `core.untrackedCache=true` enables the untracked cache. This setting assumes +that mtime is working on your machine. diff --git a/Documentation/config/fetch.txt b/Documentation/config/fetch.txt index cbfad6cdbb..63748c02b7 100644 --- a/Documentation/config/fetch.txt +++ b/Documentation/config/fetch.txt @@ -1,11 +1,14 @@ fetch.recurseSubmodules:: - This option can be either set to a boolean value or to 'on-demand'. + This option controls whether `git fetch` (and the underlying fetch + in `git pull`) will recursively fetch into populated submodules. + This option can be set either to a boolean value or to 'on-demand'. Setting it to a boolean changes the behavior of fetch and pull to - unconditionally recurse into submodules when set to true or to not - recurse at all when set to false. When set to 'on-demand' (the default - value), fetch and pull will only recurse into a populated submodule - when its superproject retrieves a commit that updates the submodule's + recurse unconditionally into submodules when set to true or to not + recurse at all when set to false. When set to 'on-demand', fetch and + pull will only recurse into a populated submodule when its + superproject retrieves a commit that updates the submodule's reference. + Defaults to 'on-demand', or to the value of 'submodule.recurse' if set. fetch.fsckObjects:: If it is set to true, git-fetch-pack will check all fetched @@ -57,9 +60,38 @@ fetch.negotiationAlgorithm:: sent when negotiating the contents of the packfile to be sent by the server. Set to "skipping" to use an algorithm that skips commits in an effort to converge faster, but may result in a larger-than-necessary - packfile; The default is "default" which instructs Git to use the default algorithm + packfile; or set to "noop" to not send any information at all, which + will almost certainly result in a larger-than-necessary packfile, but + will skip the negotiation step. + The default is "default" which instructs Git to use the default algorithm that never skips commits (unless the server has acknowledged it or one - of its descendants). + of its descendants). If `feature.experimental` is enabled, then this + setting defaults to "skipping". Unknown values will cause 'git fetch' to error out. + -See also the `--negotiation-tip` option for linkgit:git-fetch[1]. +See also the `--negotiate-only` and `--negotiation-tip` options to +linkgit:git-fetch[1]. + +fetch.showForcedUpdates:: + Set to false to enable `--no-show-forced-updates` in + linkgit:git-fetch[1] and linkgit:git-pull[1] commands. + Defaults to true. + +fetch.parallel:: + Specifies the maximal number of fetch operations to be run in parallel + at a time (submodules, or remotes when the `--multiple` option of + linkgit:git-fetch[1] is in effect). ++ +A value of 0 will give some reasonable default. If unset, it defaults to 1. ++ +For submodules, this setting can be overridden using the `submodule.fetchJobs` +config setting. + +fetch.writeCommitGraph:: + Set to true to write a commit-graph after every `git fetch` command + that downloads a pack-file from a remote. Using the `--split` option, + most executions will create a very small commit-graph file on top of + the existing commit-graph file(s). Occasionally, these files will + merge and the write may take longer. Having an updated commit-graph + file helps performance of many Git commands, including `git merge-base`, + `git push -f`, and `git log --graph`. Defaults to false. diff --git a/Documentation/config/fmt-merge-msg.txt b/Documentation/config/fmt-merge-msg.txt index c73cfa90b7..3fbf40e24f 100644 --- a/Documentation/config/fmt-merge-msg.txt +++ b/Documentation/config/fmt-merge-msg.txt @@ -8,3 +8,15 @@ merge.log:: most the specified number of one-line descriptions from the actual commits that are being merged. Defaults to false, and true is a synonym for 20. + +merge.suppressDest:: + By adding a glob that matches the names of integration + branches to this multi-valued configuration variable, the + default merge message computed for merges into these + integration branches will omit "into <branch name>" from + its title. ++ +An element with an empty value can be used to clear the list +of globs accumulated from previous configuration entries. +When there is no `merge.suppressDest` variable defined, the +default value of `master` is used for backward compatibility. diff --git a/Documentation/config/format.txt b/Documentation/config/format.txt index dc77941c48..fdbc06a4d2 100644 --- a/Documentation/config/format.txt +++ b/Documentation/config/format.txt @@ -36,6 +36,12 @@ format.subjectPrefix:: The default for format-patch is to output files with the '[PATCH]' subject prefix. Use this variable to change that prefix. +format.coverFromDescription:: + The default mode for format-patch to determine which parts of + the cover letter will be populated using the branch's + description. See the `--cover-from-description` option in + linkgit:git-format-patch[1]. + format.signature:: The default for format-patch is to output a signature containing the Git version number. Use this variable to change that default. @@ -51,6 +57,11 @@ format.suffix:: `.patch`. Use this variable to change that suffix (make sure to include the dot if you want it). +format.encodeEmailHeaders:: + Encode email headers that have non-ASCII characters with + "Q-encoding" (described in RFC 2047) for email transmission. + Defaults to true. + format.pretty:: The default pretty format for log/show/whatchanged command, See linkgit:git-log[1], linkgit:git-show[1], @@ -68,7 +79,7 @@ format.thread:: format.signOff:: A boolean value which lets you enable the `-s/--signoff` option of - format-patch by default. *Note:* Adding the Signed-off-by: line to a + format-patch by default. *Note:* Adding the `Signed-off-by` trailer to a patch should be a conscious act and means that you certify you have the rights to submit this work under the same open source license. Please see the 'SubmittingPatches' document for further discussion. @@ -77,11 +88,50 @@ format.coverLetter:: A boolean that controls whether to generate a cover-letter when format-patch is invoked, but in addition can be set to "auto", to generate a cover-letter only when there's more than one patch. + Default is false. format.outputDirectory:: Set a custom directory to store the resulting files instead of the - current working directory. + current working directory. All directory components will be created. + +format.filenameMaxLength:: + The maximum length of the output filenames generated by the + `format-patch` command; defaults to 64. Can be overridden + by the `--filename-max-length=<n>` command line option. format.useAutoBase:: A boolean value which lets you enable the `--base=auto` option of - format-patch by default. + format-patch by default. Can also be set to "whenAble" to allow + enabling `--base=auto` if a suitable base is available, but to skip + adding base info otherwise without the format dying. + +format.notes:: + Provides the default value for the `--notes` option to + format-patch. Accepts a boolean value, or a ref which specifies + where to get notes. If false, format-patch defaults to + `--no-notes`. If true, format-patch defaults to `--notes`. If + set to a non-boolean value, format-patch defaults to + `--notes=<ref>`, where `ref` is the non-boolean value. Defaults + to false. ++ +If one wishes to use the ref `ref/notes/true`, please use that literal +instead. ++ +This configuration can be specified multiple times in order to allow +multiple notes refs to be included. In that case, it will behave +similarly to multiple `--[no-]notes[=]` options passed in. That is, a +value of `true` will show the default notes, a value of `<ref>` will +also show notes from that notes ref and a value of `false` will negate +previous configurations and not show notes. ++ +For example, ++ +------------ +[format] + notes = true + notes = foo + notes = false + notes = bar +------------ ++ +will only show notes from `refs/notes/bar`. diff --git a/Documentation/config/gc.txt b/Documentation/config/gc.txt index 02b92b18b5..c834e07991 100644 --- a/Documentation/config/gc.txt +++ b/Documentation/config/gc.txt @@ -44,9 +44,9 @@ gc.autoDetach:: gc.bigPackThreshold:: If non-zero, all packs larger than this limit are kept when - `git gc` is run. This is very similar to `--keep-base-pack` + `git gc` is run. This is very similar to `--keep-largest-pack` except that all packs that meet the threshold are kept, not - just the base pack. Defaults to zero. Common unit suffixes of + just the largest pack. Defaults to zero. Common unit suffixes of 'k', 'm', or 'g' are supported. + Note that if the number of kept packs is more than gc.autoPackLimit, @@ -57,13 +57,13 @@ gc.autoPackLimit and gc.bigPackThreshold should be respected again. If the amount of memory estimated for `git repack` to run smoothly is not available and `gc.bigPackThreshold` is not set, the largest pack will also be excluded (this is the equivalent of running `git gc` with -`--keep-base-pack`). +`--keep-largest-pack`). gc.writeCommitGraph:: If true, then gc will rewrite the commit-graph file when linkgit:git-gc[1] is run. When using `git gc --auto` the commit-graph will be updated if housekeeping is - required. Default is false. See linkgit:git-commit-graph[1] + required. Default is true. See linkgit:git-commit-graph[1] for details. gc.logExpiry:: diff --git a/Documentation/config/gpg.txt b/Documentation/config/gpg.txt index cce2c89245..d94025cb36 100644 --- a/Documentation/config/gpg.txt +++ b/Documentation/config/gpg.txt @@ -18,3 +18,18 @@ gpg.<format>.program:: chose. (see `gpg.program` and `gpg.format`) `gpg.program` can still be used as a legacy synonym for `gpg.openpgp.program`. The default value for `gpg.x509.program` is "gpgsm". + +gpg.minTrustLevel:: + Specifies a minimum trust level for signature verification. If + this option is unset, then signature verification for merge + operations require a key with at least `marginal` trust. Other + operations that perform signature verification require a key + with at least `undefined` trust. Setting this option overrides + the required trust-level for all operations. Supported values, + in increasing order of significance: ++ +* `undefined` +* `never` +* `marginal` +* `fully` +* `ultimate` diff --git a/Documentation/config/help.txt b/Documentation/config/help.txt index 224bbf5a28..783a90a0f9 100644 --- a/Documentation/config/help.txt +++ b/Documentation/config/help.txt @@ -8,13 +8,14 @@ help.format:: the default. 'web' and 'html' are the same. help.autoCorrect:: - Automatically correct and execute mistyped commands after - waiting for the given number of deciseconds (0.1 sec). If more - than one command can be deduced from the entered text, nothing - will be executed. If the value of this option is negative, - the corrected command will be executed immediately. If the - value is 0 - the command will be just shown but not executed. - This is the default. + If git detects typos and can identify exactly one valid command similar + to the error, git will automatically run the intended command after + waiting a duration of time defined by this configuration value in + deciseconds (0.1 sec). If this value is 0, the suggested corrections + will be shown, but not executed. If it is a negative integer, or + "immediate", the suggested command + is run immediately. If "never", suggestions are not shown at all. The + default value is zero. help.htmlPath:: Specify the path where the HTML documentation resides. File system paths diff --git a/Documentation/config/http.txt b/Documentation/config/http.txt index 5a32f5b0a5..7003661c0d 100644 --- a/Documentation/config/http.txt +++ b/Documentation/config/http.txt @@ -29,6 +29,27 @@ http.proxyAuthMethod:: * `ntlm` - NTLM authentication (compare the --ntlm option of `curl(1)`) -- +http.proxySSLCert:: + The pathname of a file that stores a client certificate to use to authenticate + with an HTTPS proxy. Can be overridden by the `GIT_PROXY_SSL_CERT` environment + variable. + +http.proxySSLKey:: + The pathname of a file that stores a private key to use to authenticate with + an HTTPS proxy. Can be overridden by the `GIT_PROXY_SSL_KEY` environment + variable. + +http.proxySSLCertPasswordProtected:: + Enable Git's password prompt for the proxy SSL certificate. Otherwise OpenSSL + will prompt the user, possibly many times, if the certificate or private key + is encrypted. Can be overridden by the `GIT_PROXY_SSL_CERT_PASSWORD_PROTECTED` + environment variable. + +http.proxySSLCAInfo:: + Pathname to the file containing the certificate bundle that should be used to + verify the proxy with when using an HTTPS proxy. Can be overridden by the + `GIT_PROXY_SSL_CAINFO` environment variable. + http.emptyAuth:: Attempt authentication without seeking a username or password. This can be used to attempt GSS-Negotiate authentication without specifying @@ -71,7 +92,7 @@ http.saveCookies:: 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 + on libcurl. Currently the possible values of this option are: - HTTP/2 @@ -84,7 +105,7 @@ http.sslVersion:: particular configuration of the crypto library in use. Internally this sets the 'CURLOPT_SSL_VERSION' option; see the libcurl documentation for more details on the format of this option and - for the ssl version supported. Actually the possible values of + for the ssl version supported. Currently the possible values of this option are: - sslv2 @@ -199,6 +220,14 @@ http.postBuffer:: Transfer-Encoding: chunked is used to avoid creating a massive pack file locally. Default is 1 MiB, which is sufficient for most requests. ++ +Note that raising this limit is only effective for disabling chunked +transfer encoding and therefore should be used only where the remote +server or a proxy only supports HTTP/1.0 or is noncompliant with the +HTTP standard. Raising this is not, in general, an effective solution +for most push problems, but can increase memory consumption +significantly since the entire buffer is allocated even for small +pushes. http.lowSpeedLimit, http.lowSpeedTime:: If the HTTP transfer speed is less than 'http.lowSpeedLimit' diff --git a/Documentation/config/index.txt b/Documentation/config/index.txt index f181503041..75f3a2d105 100644 --- a/Documentation/config/index.txt +++ b/Documentation/config/index.txt @@ -14,6 +14,11 @@ index.recordOffsetTable:: Defaults to 'true' if index.threads has been explicitly enabled, 'false' otherwise. +index.sparse:: + When enabled, write the index using sparse-directory entries. This + has no effect unless `core.sparseCheckout` and + `core.sparseCheckoutCone` are both enabled. Defaults to 'false'. + index.threads:: Specifies the number of threads to spawn when loading the index. This is meant to reduce index load time on multiprocessor machines. @@ -24,3 +29,4 @@ index.threads:: index.version:: Specify the version with which new index files should be initialized. This does not affect existing repositories. + If `feature.manyFiles` is enabled, then the default is 4. diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt index 46fa8c6a08..79c79d6617 100644 --- a/Documentation/config/init.txt +++ b/Documentation/config/init.txt @@ -1,3 +1,7 @@ init.templateDir:: Specify the directory from which templates will be copied. (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].) + +init.defaultBranch:: + Allows overriding the default branch name e.g. when initializing + a new repository. diff --git a/Documentation/config/interactive.txt b/Documentation/config/interactive.txt index ad846dd7c9..a2d3c7ec44 100644 --- a/Documentation/config/interactive.txt +++ b/Documentation/config/interactive.txt @@ -2,7 +2,8 @@ interactive.singleKey:: In interactive commands, allow the user to provide one-letter input with a single key (i.e., without hitting enter). Currently this is used by the `--patch` mode of - linkgit:git-add[1], linkgit:git-checkout[1], linkgit:git-commit[1], + linkgit:git-add[1], linkgit:git-checkout[1], + linkgit:git-restore[1], linkgit:git-commit[1], linkgit:git-reset[1], and linkgit:git-stash[1]. Note that this setting is silently ignored if portable keystroke input is not available; requires the Perl module Term::ReadKey. diff --git a/Documentation/config/log.txt b/Documentation/config/log.txt index 78d9e4453a..456eb07800 100644 --- a/Documentation/config/log.txt +++ b/Documentation/config/log.txt @@ -18,6 +18,17 @@ log.decorate:: names are shown. This is the same as the `--decorate` option of the `git log`. +log.excludeDecoration:: + Exclude the specified patterns from the log decorations. This is + similar to the `--decorate-refs-exclude` command-line option, but + the config option can be overridden by the `--decorate-refs` + option. + +log.diffMerges:: + Set default diff format to be used for merge commits. See + `--diff-merges` in linkgit:git-log[1] for details. + Defaults to `separate`. + log.follow:: If `true`, `git log` will act as if the `--follow` option was used when a single <path> is given. This has the same limitations as `--follow`, @@ -40,4 +51,5 @@ log.showSignature:: log.mailmap:: If true, makes linkgit:git-log[1], linkgit:git-show[1], and - linkgit:git-whatchanged[1] assume `--use-mailmap`. + linkgit:git-whatchanged[1] assume `--use-mailmap`, otherwise + assume `--no-use-mailmap`. True by default. diff --git a/Documentation/config/lsrefs.txt b/Documentation/config/lsrefs.txt new file mode 100644 index 0000000000..adeda0f24d --- /dev/null +++ b/Documentation/config/lsrefs.txt @@ -0,0 +1,9 @@ +lsrefs.unborn:: + May be "advertise" (the default), "allow", or "ignore". If "advertise", + the server will respond to the client sending "unborn" (as described in + protocol-v2.txt) and will advertise support for this feature during the + protocol v2 capability advertisement. "allow" is the same as + "advertise" except that the server will not advertise support for this + feature; this is useful for load-balanced servers that cannot be + updated atomically (for example), since the administrator could + configure "allow", then after a delay, configure "advertise". diff --git a/Documentation/config/maintenance.txt b/Documentation/config/maintenance.txt new file mode 100644 index 0000000000..18f0562131 --- /dev/null +++ b/Documentation/config/maintenance.txt @@ -0,0 +1,60 @@ +maintenance.auto:: + This boolean config option controls whether some commands run + `git maintenance run --auto` after doing their normal work. Defaults + to true. + +maintenance.strategy:: + This string config option provides a way to specify one of a few + recommended schedules for background maintenance. This only affects + which tasks are run during `git maintenance run --schedule=X` + commands, provided no `--task=<task>` arguments are provided. + Further, if a `maintenance.<task>.schedule` config value is set, + then that value is used instead of the one provided by + `maintenance.strategy`. The possible strategy strings are: ++ +* `none`: This default setting implies no task are run at any schedule. +* `incremental`: This setting optimizes for performing small maintenance + activities that do not delete any data. This does not schedule the `gc` + task, but runs the `prefetch` and `commit-graph` tasks hourly, the + `loose-objects` and `incremental-repack` tasks daily, and the `pack-refs` + task weekly. + +maintenance.<task>.enabled:: + This boolean config option controls whether the maintenance task + with name `<task>` is run when no `--task` option is specified to + `git maintenance run`. These config values are ignored if a + `--task` option exists. By default, only `maintenance.gc.enabled` + is true. + +maintenance.<task>.schedule:: + This config option controls whether or not the given `<task>` runs + during a `git maintenance run --schedule=<frequency>` command. The + value must be one of "hourly", "daily", or "weekly". + +maintenance.commit-graph.auto:: + This integer config option controls how often the `commit-graph` task + should be run as part of `git maintenance run --auto`. If zero, then + the `commit-graph` task will not run with the `--auto` option. A + negative value will force the task to run every time. Otherwise, a + positive value implies the command should run when the number of + reachable commits that are not in the commit-graph file is at least + the value of `maintenance.commit-graph.auto`. The default value is + 100. + +maintenance.loose-objects.auto:: + This integer config option controls how often the `loose-objects` task + should be run as part of `git maintenance run --auto`. If zero, then + the `loose-objects` task will not run with the `--auto` option. A + negative value will force the task to run every time. Otherwise, a + positive value implies the command should run when the number of + loose objects is at least the value of `maintenance.loose-objects.auto`. + The default value is 100. + +maintenance.incremental-repack.auto:: + This integer config option controls how often the `incremental-repack` + task should be run as part of `git maintenance run --auto`. If zero, + then the `incremental-repack` task will not run with the `--auto` + option. A negative value will force the task to run every time. + Otherwise, a positive value implies the command should run when the + number of pack-files not in the multi-pack-index is at least the value + of `maintenance.incremental-repack.auto`. The default value is 10. diff --git a/Documentation/config/merge.txt b/Documentation/config/merge.txt index 6a313937f8..e27cc63944 100644 --- a/Documentation/config/merge.txt +++ b/Documentation/config/merge.txt @@ -14,7 +14,7 @@ merge.defaultToUpstream:: branches at the remote named by `branch.<current branch>.remote` are consulted, and then they are mapped via `remote.<remote>.fetch` to their corresponding remote-tracking branches, and the tips of - these tracking branches are merged. + these tracking branches are merged. Defaults to true. merge.ff:: By default, Git does not create an extra merge commit when merging @@ -33,10 +33,12 @@ merge.verifySignatures:: include::fmt-merge-msg.txt[] merge.renameLimit:: - The number of files to consider when performing rename detection - during a merge; if not specified, defaults to the value of - diff.renameLimit. This setting has no effect if rename detection - is turned off. + The number of files to consider in the exhaustive portion of + rename detection during a merge. If not specified, defaults + to the value of diff.renameLimit. If neither + merge.renameLimit nor diff.renameLimit are specified, + currently defaults to 7000. This setting has no effect if + rename detection is turned off. merge.renames:: Whether Git detects renames. If set to "false", rename detection @@ -70,6 +72,16 @@ merge.stat:: Whether to print the diffstat between ORIG_HEAD and the merge result at the end of the merge. True by default. +merge.autoStash:: + When set to true, automatically create a temporary stash entry + before the operation begins, and apply it after the operation + ends. This means that you can run merge on a dirty worktree. + However, use with care: the final stash application after a + successful merge might result in non-trivial conflicts. + This option can be overridden by the `--no-autostash` and + `--autostash` options of linkgit:git-merge[1]. + Defaults to false. + merge.tool:: Controls which merge tool is used by linkgit:git-mergetool[1]. The list below shows the valid built-in values. diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.txt index 09ed31dbfa..cafbbef46a 100644 --- a/Documentation/config/mergetool.txt +++ b/Documentation/config/mergetool.txt @@ -13,6 +13,11 @@ mergetool.<tool>.cmd:: merged; 'MERGED' contains the name of the file to which the merge tool should write the results of a successful merge. +mergetool.<tool>.hideResolved:: + Allows the user to override the global `mergetool.hideResolved` value + for a specific tool. See `mergetool.hideResolved` for the full + description. + mergetool.<tool>.trustExitCode:: For a custom merge command, specify whether the exit code of the merge command can be used to determine whether the merge was @@ -30,6 +35,26 @@ mergetool.meld.hasOutput:: to `true` tells Git to unconditionally use the `--output` option, and `false` avoids using `--output`. +mergetool.meld.useAutoMerge:: + When the `--auto-merge` is given, meld will merge all non-conflicting + parts automatically, highlight the conflicting parts and wait for + user decision. Setting `mergetool.meld.useAutoMerge` to `true` tells + Git to unconditionally use the `--auto-merge` option with `meld`. + Setting this value to `auto` makes git detect whether `--auto-merge` + is supported and will only use `--auto-merge` when available. A + value of `false` avoids using `--auto-merge` altogether, and is the + default value. + +mergetool.hideResolved:: + During a merge Git will automatically resolve as many conflicts as + possible and write the 'MERGED' file containing conflict markers around + any conflicts that it cannot resolve; 'LOCAL' and 'REMOTE' normally + represent the versions of the file from before Git's conflict + resolution. This flag causes 'LOCAL' and 'REMOTE' to be overwriten so + that only the unresolved conflicts are presented to the merge tool. Can + be configured per-tool via the `mergetool.<tool>.hideResolved` + configuration variable. Defaults to `false`. + mergetool.keepBackup:: After performing a merge, the original file with conflict markers can be saved as a file with a `.orig` extension. If this variable diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.txt index 9cdcfa7324..763f7af7c4 100644 --- a/Documentation/config/pack.txt +++ b/Documentation/config/pack.txt @@ -27,6 +27,13 @@ Note that changing the compression level will not automatically recompress all existing objects. You can force recompression by passing the -F option to linkgit:git-repack[1]. +pack.allowPackReuse:: + When true, and when reachability bitmaps are enabled, + pack-objects will try to send parts of the bitmapped packfile + verbatim. This can reduce memory and CPU usage to serve fetches, + but might result in sending a slightly larger pack. Defaults to + true. + pack.island:: An extended regular expression configuring a set of delta islands. See "DELTA ISLANDS" in linkgit:git-pack-objects[1] @@ -92,12 +99,23 @@ pack.packSizeLimit:: packing to a file when repacking, i.e. the git:// protocol is unaffected. It can be overridden by the `--max-pack-size` option of linkgit:git-repack[1]. Reaching this limit results - in the creation of multiple packfiles; which in turn prevents - bitmaps from being created. - The minimum size allowed is limited to 1 MiB. - The default is unlimited. - Common unit suffixes of 'k', 'm', or 'g' are - supported. + in the creation of multiple packfiles. ++ +Note that this option is rarely useful, and may result in a larger total +on-disk size (because Git will not store deltas between packs), as well +as worse runtime performance (object lookup within multiple packs is +slower than a single pack, and optimizations like reachability bitmaps +cannot cope with multiple packs). ++ +If you need to actively run Git using smaller packfiles (e.g., because your +filesystem does not support large files), this option may help. But if +your goal is to transmit a packfile over a medium that supports limited +sizes (e.g., removable media that cannot store the whole repository), +you are likely better off creating a single large packfile and splitting +it using a generic multi-volume archive tool (e.g., Unix `split`). ++ +The minimum size allowed is limited to 1 MiB. The default is unlimited. +Common unit suffixes of 'k', 'm', or 'g' are supported. pack.useBitmaps:: When true, git will use pack bitmaps (if available) when packing @@ -112,7 +130,23 @@ pack.useSparse:: 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. + commits contain certain types of direct renames. Default is + `true`. + +pack.preferBitmapTips:: + When selecting which commits will receive bitmaps, prefer a + commit at the tip of any reference that is a suffix of any value + of this configuration over any other commits in the "selection + window". ++ +Note that setting this configuration to `refs/foo` does not mean that +the commits at the tips of `refs/foo/bar` and `refs/foo/baz` will +necessarily be selected. This is because commits are selected for +bitmaps from within a series of windows of variable length. ++ +If a commit at the tip of any reference which is a suffix of any value +of this configuration is seen in a window, it is immediately given +preference over any other commit in that window. pack.writeBitmaps (deprecated):: This is a deprecated synonym for `repack.writeBitmaps`. @@ -125,3 +159,10 @@ pack.writeBitmapHashCache:: between an older, bitmapped pack and objects that have been pushed since the last gc). The downside is that it consumes 4 bytes per object of disk space. Defaults to true. + +pack.writeReverseIndex:: + When true, git will write a corresponding .rev file (see: + link:../technical/pack-format.html[Documentation/technical/pack-format.txt]) + for each new packfile that it writes in all places except for + linkgit:git-fast-import[1] and in the bulk checkin mechanism. + Defaults to false. diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.txt index bfccc07491..756591d77b 100644 --- a/Documentation/config/protocol.txt +++ b/Documentation/config/protocol.txt @@ -45,11 +45,10 @@ The protocol names currently used by git are: -- protocol.version:: - Experimental. If set, clients will attempt to communicate with a - server using the specified protocol version. If unset, no - attempt will be made by the client to communicate using a - particular protocol version, this results in protocol version 0 - being used. + If set, clients will attempt to communicate with a server + using the specified protocol version. If the server does + not support it, communication falls back to version 0. + If unset, the default is `2`. Supported versions: + -- diff --git a/Documentation/config/pull.txt b/Documentation/config/pull.txt index b87cab31b3..5404830609 100644 --- a/Documentation/config/pull.txt +++ b/Documentation/config/pull.txt @@ -14,15 +14,16 @@ pull.rebase:: pull" is run. See "branch.<name>.rebase" for setting this on a per-branch basis. + -When `merges`, pass the `--rebase-merges` option to 'git rebase' +When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase' so that the local merge commits are included in the rebase (see linkgit:git-rebase[1] for details). + -When `preserve` (deprecated in favor of `merges`), also pass +When `preserve` (or just 'p', deprecated in favor of `merges`), also pass `--preserve-merges` along to 'git rebase' so that locally committed merge commits will not be flattened by running 'git pull'. + -When the value is `interactive`, the rebase is run in interactive mode. +When the value is `interactive` (or just 'i'), the rebase is run in interactive +mode. + *NOTE*: this is a possibly dangerous operation; do *not* use it unless you understand the implications (see linkgit:git-rebase[1] diff --git a/Documentation/config/push.txt b/Documentation/config/push.txt index 0a0e000569..632033638c 100644 --- a/Documentation/config/push.txt +++ b/Documentation/config/push.txt @@ -1,6 +1,7 @@ push.default:: Defines the action `git push` should take if no refspec is - explicitly given. Different values are well-suited for + given (whether from the command-line, config, or elsewhere). + Different values are well-suited for specific workflows; for instance, in a purely central workflow (i.e. the fetch source is equal to the push destination), `upstream` is probably what you want. Possible values are: @@ -8,7 +9,7 @@ push.default:: -- * `nothing` - do not push anything (error out) unless a refspec is - explicitly given. This is primarily meant for people who want to + given. This is primarily meant for people who want to avoid mistakes by always being explicit. * `current` - push the current branch to update a branch with the same @@ -23,15 +24,14 @@ push.default:: * `tracking` - This is a deprecated synonym for `upstream`. -* `simple` - in centralized workflow, work like `upstream` with an - added safety to refuse to push if the upstream branch's name is - different from the local one. +* `simple` - pushes the current branch with the same name on the remote. + -When pushing to a remote that is different from the remote you normally -pull from, work as `current`. This is the safest option and is suited -for beginners. +If you are working on a centralized workflow (pushing to the same repository you +pull from, which is typically `origin`), then you need to configure an upstream +branch with the same name. + -This mode has become the default in Git 2.0. +This mode is the default since Git 2.0, and is the safest option suited for +beginners. * `matching` - push all branches having the same name on both ends. This makes the repository you are pushing to remember the set of @@ -79,7 +79,7 @@ higher priority configuration file (e.g. `.git/config` in a repository) to clear the values inherited from a lower priority configuration files (e.g. `$HOME/.gitconfig`). + --- +---- Example: @@ -96,7 +96,7 @@ repo/.git/config This will result in only b (a and c are cleared). --- +---- push.recurseSubmodules:: Make sure all submodule commits used by the revisions to be pushed @@ -111,3 +111,18 @@ push.recurseSubmodules:: is 'no' then default behavior of ignoring submodules when pushing is retained. You may override this configuration at time of push by specifying '--recurse-submodules=check|on-demand|no'. + If not set, 'no' is used by default, unless 'submodule.recurse' is + set (in which case a 'true' value means 'on-demand'). + +push.useForceIfIncludes:: + If set to "true", it is equivalent to specifying + `--force-if-includes` as an option to linkgit:git-push[1] + in the command line. Adding `--no-force-if-includes` at the + time of push overrides this configuration setting. + +push.negotiate:: + If set to "true", attempt to reduce the size of the packfile + sent by rounds of negotiation in which the client and the + server attempt to find commits in common. If "false", Git will + rely solely on the server's ref advertisement to find commits + in common. diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.txt index d98e32d812..8c979cb20f 100644 --- a/Documentation/config/rebase.txt +++ b/Documentation/config/rebase.txt @@ -1,9 +1,8 @@ -rebase.useBuiltin:: - Unused configuration variable. Used in Git versions 2.20 and - 2.21 as an escape hatch to enable the legacy shellscript - implementation of rebase. Now the built-in rewrite of it in C - is always used. Setting this will emit a warning, to alert any - remaining users that setting this now does nothing. +rebase.backend:: + Default backend to use for rebasing. Possible choices are + 'apply' or 'merge'. In the future, if the merge backend gains + all remaining capabilities of the apply backend, this setting + may become unused. rebase.stat:: Whether to show a diffstat of what changed upstream since the last @@ -62,3 +61,6 @@ 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. + +rebase.forkPoint:: + If set to false set `--no-fork-point` option by default. diff --git a/Documentation/config/receive.txt b/Documentation/config/receive.txt index 65f78aac37..85d5b5a3d2 100644 --- a/Documentation/config/receive.txt +++ b/Documentation/config/receive.txt @@ -114,6 +114,28 @@ receive.hideRefs:: An attempt to update or delete a hidden ref by `git push` is rejected. +receive.procReceiveRefs:: + This is a multi-valued variable that defines reference prefixes + to match the commands in `receive-pack`. Commands matching the + prefixes will be executed by an external hook "proc-receive", + instead of the internal `execute_commands` function. If this + variable is not defined, the "proc-receive" hook will never be + used, and all commands will be executed by the internal + `execute_commands` function. ++ +For example, if this variable is set to "refs/for", pushing to reference +such as "refs/for/master" will not create or update a reference named +"refs/for/master", but may create or update a pull request directly by +running the hook "proc-receive". ++ +Optional modifiers can be provided in the beginning of the value to filter +commands for specific actions: create (a), modify (m), delete (d). +A `!` can be included in the modifiers to negate the reference prefix entry. +E.g.: ++ + git config --system --add receive.procReceiveRefs ad:refs/heads + git config --system --add receive.procReceiveRefs !:refs/heads + receive.updateServerInfo:: If set to true, git-receive-pack will run git-update-server-info after receiving data from git-push and updating refs. diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.txt index 6c4cad83a2..a8e6437a90 100644 --- a/Documentation/config/remote.txt +++ b/Documentation/config/remote.txt @@ -76,3 +76,11 @@ remote.<name>.pruneTags:: + See also `remote.<name>.prune` and the PRUNING section of linkgit:git-fetch[1]. + +remote.<name>.promisor:: + When set to true, this remote will be used to fetch promisor + objects. + +remote.<name>.partialclonefilter:: + The filter that will be applied when fetching from this + promisor remote. diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt index 0006faf800..50baa5d6bf 100644 --- a/Documentation/config/sendemail.txt +++ b/Documentation/config/sendemail.txt @@ -8,9 +8,6 @@ sendemail.smtpEncryption:: See linkgit:git-send-email[1] for description. Note that this setting is not subject to the 'identity' mechanism. -sendemail.smtpssl (deprecated):: - Deprecated alias for 'sendemail.smtpEncryption = ssl'. - sendemail.smtpsslcertpath:: Path to ca-certificates (either a directory or a single file). Set it to an empty string to disable certificate verification. @@ -61,3 +58,8 @@ sendemail.smtpBatchSize:: sendemail.smtpReloginDelay:: Seconds wait before reconnecting to smtp server. See also the `--relogin-delay` option of linkgit:git-send-email[1]. + +sendemail.forbidSendmailVariables:: + To avoid common misconfiguration mistakes, linkgit:git-send-email[1] + will abort with a warning if any configuration options for "sendmail" + exist. Set this variable to bypass the check. diff --git a/Documentation/config/stash.txt b/Documentation/config/stash.txt index 7710758efb..9ed775281f 100644 --- a/Documentation/config/stash.txt +++ b/Documentation/config/stash.txt @@ -1,17 +1,14 @@ stash.useBuiltin:: - Set to `false` to use the legacy shell script implementation of - linkgit:git-stash[1]. Is `true` by default, which means use - the built-in rewrite of it in C. -+ -The C rewrite is first included with Git version 2.22 (and Git for Windows -version 2.19). This option serves an an escape hatch to re-enable the -legacy version in case any bugs are found in the rewrite. This option and -the shell script version of linkgit:git-stash[1] will be removed in some -future release. -+ -If you find some reason to set this option to `false`, other than -one-off testing, you should report the behavior difference as a bug in -Git (see https://git-scm.com/community for details). + Unused configuration variable. Used in Git versions 2.22 to + 2.26 as an escape hatch to enable the legacy shellscript + implementation of stash. Now the built-in rewrite of it in C + is always used. Setting this will emit a warning, to alert any + remaining users that setting this now does nothing. + +stash.showIncludeUntracked:: + If this is set to true, the `git stash show` command will show + the untracked files of a stash entry. Defaults to false. See + description of 'show' command in linkgit:git-stash[1]. stash.showPatch:: If this is set to true, the `git stash show` command without an diff --git a/Documentation/config/status.txt b/Documentation/config/status.txt index ed72fa7dae..0fc704ab80 100644 --- a/Documentation/config/status.txt +++ b/Documentation/config/status.txt @@ -12,6 +12,11 @@ status.branch:: Set to true to enable --branch by default in linkgit:git-status[1]. The option --no-branch takes precedence over this variable. +status.aheadBehind:: + Set to true to enable `--ahead-behind` and false to enable + `--no-ahead-behind` by default in linkgit:git-status[1] for + non-porcelain status formats. Defaults to true. + status.displayCommentPrefix:: If set to true, linkgit:git-status[1] will insert a comment prefix before each output line (starting with diff --git a/Documentation/config/submodule.txt b/Documentation/config/submodule.txt index 0a1293b051..ee454f8126 100644 --- a/Documentation/config/submodule.txt +++ b/Documentation/config/submodule.txt @@ -58,10 +58,19 @@ submodule.active:: commands. See linkgit:gitsubmodules[7] for details. submodule.recurse:: - Specifies if commands recurse into submodules by default. This - applies to all commands that have a `--recurse-submodules` option, - except `clone`. + A boolean indicating if commands should enable the `--recurse-submodules` + option by default. + Applies to all commands that support this option + (`checkout`, `fetch`, `grep`, `pull`, `push`, `read-tree`, `reset`, + `restore` and `switch`) except `clone` and `ls-files`. Defaults to false. + When set to true, it can be deactivated via the + `--no-recurse-submodules` option. Note that some Git commands + lacking this option may call some of the above commands affected by + `submodule.recurse`; for instance `git remote update` will call + `git fetch` but does not have a `--no-recurse-submodules` option. + For these commands a workaround is to temporarily change the + configuration value by using `git -c submodule.recurse=0`. submodule.fetchJobs:: Specifies how many submodules are fetched/cloned at the same time. @@ -79,4 +88,6 @@ submodule.alternateLocation:: submodule.alternateErrorStrategy:: Specifies how to treat errors with the alternates for a submodule as computed via `submodule.alternateLocation`. Possible values are - `ignore`, `info`, `die`. Default is `die`. + `ignore`, `info`, `die`. Default is `die`. Note that if set to `ignore` + or `info`, and if there is an error with the computed alternate, the + clone proceeds as if no alternate was specified. diff --git a/Documentation/config/tag.txt b/Documentation/config/tag.txt index 663663bdec..5062a057ff 100644 --- a/Documentation/config/tag.txt +++ b/Documentation/config/tag.txt @@ -8,9 +8,10 @@ tag.sort:: linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the value of this variable will be used as the default. -tar.umask:: - This variable can be used to restrict the permission bits of - tar archive entries. The default is 0002, which turns off the - world write bit. The special value "user" indicates that the - archiving user's umask will be used instead. See umask(2) and - linkgit:git-archive[1]. +tag.gpgSign:: + A boolean to specify whether all tags should be GPG signed. + Use of this option when running in an automated script can + result in a large number of tags being signed. It is therefore + convenient to use an agent to avoid typing your gpg passphrase + several times. Note that this option doesn't affect tag signing + behavior enabled by "-u <keyid>" or "--local-user=<keyid>" options. diff --git a/Documentation/config/tar.txt b/Documentation/config/tar.txt new file mode 100644 index 0000000000..de8ff48ea9 --- /dev/null +++ b/Documentation/config/tar.txt @@ -0,0 +1,6 @@ +tar.umask:: + This variable can be used to restrict the permission bits of + tar archive entries. The default is 0002, which turns off the + world write bit. The special value "user" indicates that the + archiving user's umask will be used instead. See umask(2) and + linkgit:git-archive[1]. diff --git a/Documentation/config/trace2.txt b/Documentation/config/trace2.txt index 2edbfb02fe..fe1642f0d4 100644 --- a/Documentation/config/trace2.txt +++ b/Documentation/config/trace2.txt @@ -48,9 +48,24 @@ trace2.configParams:: May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment variable. Unset by default. +trace2.envVars:: + A comma-separated list of "important" environment variables that should + be recorded in the trace2 output. For example, + `GIT_HTTP_USER_AGENT,GIT_CONFIG` would cause the trace2 output to + contain events listing the overrides for HTTP user agent and the + location of the Git configuration file (assuming any are set). May be + overridden by the `GIT_TRACE2_ENV_VARS` environment variable. Unset by + default. + trace2.destinationDebug:: Boolean. When true Git will print error messages when a trace target destination cannot be opened for writing. By default, these errors are suppressed and tracing is silently disabled. May be overridden by the `GIT_TRACE2_DST_DEBUG` environment variable. + +trace2.maxFiles:: + Integer. When writing trace files to a target directory, do not + write additional traces if we would exceed this many files. Instead, + write a sentinel file that will block further tracing to this + directory. Defaults to 0, which disables this check. diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.txt index 4a5dfe2fc1..505126a780 100644 --- a/Documentation/config/transfer.txt +++ b/Documentation/config/transfer.txt @@ -17,7 +17,7 @@ linkgit:git-receive-pack[1]. On the fetch side, malformed objects will instead be left unreferenced in the repository. + Due to the non-quarantine nature of the `fetch.fsckObjects` -implementation it can not be relied upon to leave the object store +implementation it cannot be relied upon to leave the object store clean like `receive.fsckObjects` can. + As objects are unpacked they're written to the object store, so there @@ -69,3 +69,7 @@ transfer.unpackLimit:: When `fetch.unpackLimit` or `receive.unpackLimit` are not set, the value of this variable is used instead. The default value is 100. + +transfer.advertiseSID:: + Boolean. When true, client and server processes will advertise their + unique session IDs to their remote counterpart. Defaults to false. diff --git a/Documentation/config/uploadpack.txt b/Documentation/config/uploadpack.txt index ed1c835695..32fad5bbe8 100644 --- a/Documentation/config/uploadpack.txt +++ b/Documentation/config/uploadpack.txt @@ -57,6 +57,25 @@ uploadpack.allowFilter:: If this option is set, `upload-pack` will support partial clone and partial fetch object filtering. +uploadpackfilter.allow:: + Provides a default value for unspecified object filters (see: the + below configuration variable). If set to `true`, this will also + enable all filters which get added in the future. + Defaults to `true`. + +uploadpackfilter.<filter>.allow:: + Explicitly allow or ban the object filter corresponding to + `<filter>`, where `<filter>` may be one of: `blob:none`, + `blob:limit`, `object:type`, `tree`, `sparse:oid`, or `combine`. + If using combined filters, both `combine` and all of the nested + filter kinds must be allowed. Defaults to `uploadpackfilter.allow`. + +uploadpackfilter.tree.maxDepth:: + Only allow `--filter=tree:<n>` when `<n>` is no more than the value of + `uploadpackfilter.tree.maxDepth`. If set, this also implies + `uploadpackfilter.tree.allow=true`, unless this configuration + variable had already been set. Has no effect if unset. + uploadpack.allowRefInWant:: If this option is set, `upload-pack` will support the `ref-in-want` feature of the protocol version 2 `fetch` command. This feature diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt index 0557cbbceb..59aec7c3ae 100644 --- a/Documentation/config/user.txt +++ b/Documentation/config/user.txt @@ -13,7 +13,12 @@ committer.email:: Also, all of these can be overridden by the `GIT_AUTHOR_NAME`, `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL` and `EMAIL` environment variables. - See linkgit:git-commit-tree[1] for more information. ++ +Note that the `name` forms of these variables conventionally refer to +some form of a personal name. See linkgit:git-commit[1] and the +environment variables section of linkgit:git[1] for more information on +these settings and the `credential.username` option if you're looking +for authentication credentials instead. user.useConfigOnly:: Instruct Git to avoid trying to guess defaults for `user.email` diff --git a/Documentation/date-formats.txt b/Documentation/date-formats.txt index 6926e0a4c8..99c455f51c 100644 --- a/Documentation/date-formats.txt +++ b/Documentation/date-formats.txt @@ -1,10 +1,7 @@ DATE FORMATS ------------ -The `GIT_AUTHOR_DATE`, `GIT_COMMITTER_DATE` environment variables -ifdef::git-commit[] -and the `--date` option -endif::git-commit[] +The `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` environment variables support the following date formats: Git internal format:: @@ -20,7 +17,15 @@ RFC 2822:: ISO 8601:: Time and date specified by the ISO 8601 standard, for example `2005-04-07T22:13:13`. The parser accepts a space instead of the - `T` character as well. + `T` character as well. Fractional parts of a second will be ignored, + for example `2005-04-07T22:13:13.019` will be treated as + `2005-04-07T22:13:13`. + NOTE: In addition, the date part is accepted in the following formats: `YYYY.MM.DD`, `MM/DD/YYYY` and `DD.MM.YYYY`. + +ifdef::git-commit[] +In addition to recognizing all date formats above, the `--date` option +will also try to make sense of other, more human-centric date formats, +such as relative dates like "yesterday" or "last Friday at noon". +endif::git-commit[] diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index 4d846d7346..fbbd410a84 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -61,7 +61,7 @@ Possible status letters are: - R: renaming of a file - T: change in the type of the file - U: file is unmerged (you must complete the merge before it can -be committed) + be committed) - X: "unknown" change type (most probably a bug, please report it) Status letters C and R are always followed by a score (denoting the diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.txt index f10ca410ad..c78063d4f7 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.txt @@ -1,12 +1,17 @@ -Generating patches with -p --------------------------- - -When "git-diff-index", "git-diff-tree", or "git-diff-files" are run -with a `-p` option, "git diff" without the `--raw` option, or -"git log" with the "-p" option, they -do not produce the output described above; instead they produce a -patch file. You can customize the creation of such patches via the -`GIT_EXTERNAL_DIFF` and the `GIT_DIFF_OPTS` environment variables. +Generating patch text with -p +----------------------------- + +Running +linkgit:git-diff[1], +linkgit:git-log[1], +linkgit:git-show[1], +linkgit:git-diff-index[1], +linkgit:git-diff-tree[1], or +linkgit:git-diff-files[1] +with the `-p` option produces patch text. +You can customize the creation of patch text via the +`GIT_EXTERNAL_DIFF` and the `GIT_DIFF_OPTS` environment variables +(see linkgit:git[1]), and the `diff` attribute (see linkgit:gitattributes[5]). What the -p option produces is slightly different from the traditional diff format: @@ -49,7 +54,7 @@ similarity index value of 100% is thus reserved for two equal files, while 100% dissimilarity means that no line from the old file made it into the new one. + -The index line includes the SHA-1 checksum before and after the change. +The index line includes the blob object names before and after the change. The <mode> is included if the file mode does not change; otherwise, separate lines indicate the old and the new mode. @@ -69,18 +74,23 @@ separate lines indicate the old and the new mode. rename from b rename to a +5. Hunk headers mention the name of the function to which the hunk + applies. See "Defining a custom hunk-header" in + linkgit:gitattributes[5] for details of how to tailor to this to + specific languages. + -combined diff format +Combined diff format -------------------- Any diff-generating command can take the `-c` or `--cc` option to produce a 'combined diff' when showing a merge. This is the default format when showing merges with linkgit:git-diff[1] or -linkgit:git-show[1]. Note also that you can give the `-m` option to any -of these commands to force generation of diffs with individual parents -of a merge. +linkgit:git-show[1]. Note also that you can give suitable +`--diff-merges` option to any of these commands to force generation of +diffs in specific format. -A 'combined diff' format looks like this: +A "combined diff" format looks like this: ------------ diff --combined describe.c @@ -113,11 +123,11 @@ index fabadb8,cc95eb0..4866510 ------------ 1. It is preceded with a "git diff" header, that looks like - this (when `-c` option is used): + this (when the `-c` option is used): diff --combined file + -or like this (when `--cc` option is used): +or like this (when the `--cc` option is used): diff --cc file @@ -160,7 +170,7 @@ parents. 4. Chunk header format is modified to prevent people from accidentally feeding it to `patch -p1`. Combined diff format was created for review of merge commit changes, and was not - meant for apply. The change is similar to the change in the + meant to be applied. The change is similar to the change in the extended 'index' header: @@@ <from-file-range> <from-file-range> <to-file-range> @@@ diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 09faee3b44..c89d530d3d 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -33,12 +33,70 @@ endif::git-diff[] show the patch by default, or to cancel the effect of `--patch`. endif::git-format-patch[] +ifdef::git-log[] +--diff-merges=(off|none|on|first-parent|1|separate|m|combined|c|dense-combined|cc):: +--no-diff-merges:: + Specify diff format to be used for merge commits. Default is + {diff-merges-default} unless `--first-parent` is in use, in which case + `first-parent` is the default. ++ +--diff-merges=(off|none)::: +--no-diff-merges::: + Disable output of diffs for merge commits. Useful to override + implied value. ++ +--diff-merges=on::: +--diff-merges=m::: +-m::: + This option makes diff output for merge commits to be shown in + the default format. `-m` will produce the output only if `-p` + is given as well. The default format could be changed using + `log.diffMerges` configuration parameter, which default value + is `separate`. ++ +--diff-merges=first-parent::: +--diff-merges=1::: + This option makes merge commits show the full diff with + respect to the first parent only. ++ +--diff-merges=separate::: + This makes merge commits show the full diff with respect to + each of the parents. Separate log entry and diff is generated + for each parent. ++ +--diff-merges=combined::: +--diff-merges=c::: +-c::: + With this option, diff output for a merge commit shows the + differences from each of the parents to the merge result + simultaneously instead of showing pairwise diff between a + parent and the result one at a time. Furthermore, it lists + only files which were modified from all parents. `-c` implies + `-p`. ++ +--diff-merges=dense-combined::: +--diff-merges=cc::: +--cc::: + With this option the output produced by + `--diff-merges=combined` is further compressed by omitting + uninteresting hunks whose contents in the parents have only + two variants and the merge result picks one of them without + modification. `--cc` implies `-p`. + +--combined-all-paths:: + This flag causes combined diffs (used for merge commits) to + list the name of the file from all parents. It thus only has + effect when `--diff-merges=[dense-]combined` is in use, and + is likely only useful if filename changes are detected (i.e. + when either rename or copy detection have been requested). +endif::git-log[] + -U<n>:: --unified=<n>:: Generate diffs with <n> lines of context instead of - the usual three. Implies `--patch`. + the usual three. ifndef::git-format-patch[] - Implies `-p`. + Implies `--patch`. endif::git-format-patch[] --output=<file>:: @@ -73,6 +131,11 @@ ifndef::git-format-patch[] Synonym for `-p --raw`. endif::git-format-patch[] +ifdef::git-log[] +-t:: + Show the tree objects in the diff output. +endif::git-log[] + --indent-heuristic:: Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default. @@ -237,11 +300,14 @@ explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). --name-only:: - Show only names of changed files. + Show only names of changed files. The file names are often encoded in UTF-8. + For more information see the discussion about encoding in the linkgit:git-log[1] + manual page. --name-status:: Show only names and status of changed files. See the description of the `--diff-filter` option on what the status letters mean. + Just like `--name-only` the file names are often encoded in UTF-8. --submodule[=<format>]:: Specify how differences in submodules are shown. When specifying @@ -436,15 +502,20 @@ endif::git-format-patch[] --binary:: In addition to `--full-index`, output a binary diff that - can be applied with `git-apply`. Implies `--patch`. + can be applied with `git-apply`. +ifndef::git-format-patch[] + Implies `--patch`. +endif::git-format-patch[] --abbrev[=<n>]:: Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header - lines, show only a partial prefix. This is - independent of the `--full-index` option above, which controls - the diff-patch output format. Non default number of - digits can be specified with `--abbrev=<n>`. + lines, show the shortest prefix that is at least '<n>' + hexdigits long that uniquely refers the object. + In diff-patch output format, `--full-index` takes higher + precedence, i.e. if `--full-index` is specified, full blob + names will be shown regardless of `--abbrev`. + Non default number of digits can be specified with `--abbrev=<n>`. -B[<n>][/<m>]:: --break-rewrites[=[<n>][/<m>]]:: @@ -517,11 +588,17 @@ When used together with `-B`, omit also the preimage in the deletion part of a delete/create pair. -l<num>:: - The `-M` and `-C` options require O(n^2) processing time where n - is the number of potential rename/copy targets. This - option prevents rename/copy detection from running if - the number of rename/copy targets exceeds the specified - number. + The `-M` and `-C` options involve some preliminary steps that + can detect subsets of renames/copies cheaply, followed by an + exhaustive fallback portion that compares all remaining + unpaired destinations to all relevant sources. (For renames, + only remaining unpaired sources are relevant; for copies, all + original sources are relevant.) For N sources and + destinations, this exhaustive check is O(N^2). This option + prevents the exhaustive portion of rename/copy detection from + running if the number of source/destination files involved + exceeds the specified number. Defaults to diff.renameLimit. + Note that a value of 0 is treated as unlimited. ifndef::git-format-patch[] --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]:: @@ -567,13 +644,13 @@ To illustrate the difference between `-S<regex> --pickaxe-regex` and file: + ---- -+ return !regexec(regexp, two->ptr, 1, ®match, 0); ++ return frotz(nitfol, two->ptr, 1, 0); ... -- hit = !regexec(regexp, mf2.ptr, 1, ®match, 0); +- hit = frotz(nitfol, mf2.ptr, 1, 0); ---- + -While `git log -G"regexec\(regexp"` will show this commit, `git log --S"regexec\(regexp" --pickaxe-regex` will not (because the number of +While `git log -G"frotz\(nitfol"` will show this commit, `git log +-S"frotz\(nitfol" --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 @@ -639,19 +716,30 @@ matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". +--skip-to=<file>:: +--rotate-to=<file>:: + Discard the files before the named <file> from the output + (i.e. 'skip to'), or move them to the end of the output + (i.e. 'rotate to'). These were invented primarily for use + of the `git difftool` command, and may not be very useful + otherwise. + ifndef::git-format-patch[] -R:: Swap two inputs; that is, show differences from index or on-disk file to tree contents. +endif::git-format-patch[] --relative[=<path>]:: +--no-relative:: When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative to by giving a <path> as an argument. -endif::git-format-patch[] + `--no-relative` can be used to countermand both `diff.relative` config + option and previous `--relative`. -a:: --text:: @@ -678,6 +766,11 @@ endif::git-format-patch[] --ignore-blank-lines:: Ignore changes whose lines are all blank. +-I<regex>:: +--ignore-matching-lines=<regex>:: + Ignore changes whose all lines match <regex>. This option may + be specified more than once. + --inter-hunk-context=<lines>:: Show the context between diff hunks, up to the specified number of lines, thereby fusing hunks that are close to each other. @@ -686,7 +779,10 @@ endif::git-format-patch[] -W:: --function-context:: - Show whole surrounding functions of changes. + Show whole function as context lines for each change. + The function names are determined in the same way as + `git diff` works out patch hunk headers (see 'Defining a + custom hunk-header' in linkgit:gitattributes[5]). ifndef::git-format-patch[] ifndef::git-log[] diff --git a/Documentation/doc-diff b/Documentation/doc-diff index 3355be4798..1694300e50 100755 --- a/Documentation/doc-diff +++ b/Documentation/doc-diff @@ -21,7 +21,7 @@ asciidoc use asciidoc with both commits to-asciidoc use asciidoc with the 'to'-commit to-asciidoctor use asciidoctor with the 'to'-commit asciidoctor use asciidoctor with both commits -cut-header-footer cut away header and footer +cut-footer cut away footer " SUBDIRECTORY_OK=1 . "$(git --exec-path)/git-sh-setup" @@ -31,7 +31,7 @@ force= clean= from_program= to_program= -cut_header_footer= +cut_footer= while test $# -gt 0 do case "$1" in @@ -55,8 +55,8 @@ do --asciidoc) from_program=-asciidoc to_program=-asciidoc ;; - --cut-header-footer) - cut_header_footer=-cut-header-footer ;; + --cut-footer) + cut_footer=-cut-footer ;; --) shift; break ;; *) @@ -118,8 +118,8 @@ construct_makemanflags () { from_makemanflags=$(construct_makemanflags "$from_program") && to_makemanflags=$(construct_makemanflags "$to_program") && -from_dir=$from_oid$from_program$cut_header_footer && -to_dir=$to_oid$to_program$cut_header_footer && +from_dir=$from_oid$from_program$cut_footer && +to_dir=$to_oid$to_program$cut_footer && # generate_render_makefile <srcdir> <dstdir> generate_render_makefile () { @@ -127,7 +127,7 @@ generate_render_makefile () { while read src do dst=$2/${src#$1/} - printf 'all:: %s\n' "$dst" + printf 'all: %s\n' "$dst" printf '%s: %s\n' "$dst" "$src" printf '\t@echo >&2 " RENDER $(notdir $@)" && \\\n' printf '\tmkdir -p $(dir $@) && \\\n' @@ -169,12 +169,11 @@ render_tree () { make -j$parallel -f - && mv "$tmp/rendered/$dname+" "$tmp/rendered/$dname" - if test "$cut_header_footer" = "-cut-header-footer" + if test "$cut_footer" = "-cut-footer" then for f in $(find "$tmp/rendered/$dname" -type f) do - tail -n +3 "$f" | head -n -2 | - sed -e '1{/^$/d}' -e '${/^$/d}' >"$f+" && + head -n -2 "$f" | sed -e '${/^$/d}' >"$f+" && mv "$f+" "$f" || return 1 done diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index 91c47752ec..e967ff1874 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -7,6 +7,10 @@ existing contents of `.git/FETCH_HEAD`. Without this option old data in `.git/FETCH_HEAD` will be overwritten. +--atomic:: + Use an atomic transaction to update local refs. Either all refs are + updated, or on error, no refs are updated. + --depth=<depth>:: Limit fetching to the specified number of commits from the tip of each remote branch history. If fetching to a 'shallow' repository @@ -58,12 +62,28 @@ The argument to this option may be a glob on ref names, a ref, or the (possibly abbreviated) SHA-1 of a commit. Specifying a glob is equivalent to specifying this option multiple times, one for each matching ref name. + -See also the `fetch.negotiationAlgorithm` configuration variable -documented in linkgit:git-config[1]. +See also the `fetch.negotiationAlgorithm` and `push.negotiate` +configuration variables documented in linkgit:git-config[1], and the +`--negotiate-only` option below. + +--negotiate-only:: + Do not fetch anything from the server, and instead print the + ancestors of the provided `--negotiation-tip=*` arguments, + which we have in common with the server. ++ +Internally this is used to implement the `push.negotiate` option, see +linkgit:git-config[1]. -ifndef::git-pull[] --dry-run:: Show what would be done, without making any changes. + +ifndef::git-pull[] +--[no-]write-fetch-head:: + Write the list of remote refs fetched in the `FETCH_HEAD` + file directly under `$GIT_DIR`. This is the default. + Passing `--no-write-fetch-head` from the command line tells + Git not to write the file. Under `--dry-run` option, the + file is never written. endif::git-pull[] -f:: @@ -88,6 +108,22 @@ ifndef::git-pull[] Allow several <repository> and <group> arguments to be specified. No <refspec>s may be specified. +--[no-]auto-maintenance:: +--[no-]auto-gc:: + Run `git maintenance run --auto` at the end to perform automatic + repository maintenance if needed. (`--[no-]auto-gc` is a synonym.) + This is enabled by default. + +--[no-]write-commit-graph:: + Write a commit-graph after fetching. This overrides the config + setting `fetch.writeCommitGraph`. +endif::git-pull[] + +--prefetch:: + Modify the configured refspec to place all refs into the + `refs/prefetch/` namespace. See the `prefetch` task in + linkgit:git-maintenance[1]. + -p:: --prune:: Before fetching, remove any remote-tracking references that no @@ -99,6 +135,7 @@ ifndef::git-pull[] was cloned with the --mirror option), then they are also subject to pruning. Supplying `--prune-tags` is a shorthand for providing the tag refspec. +ifndef::git-pull[] + See the PRUNING section below for more details. @@ -125,13 +162,15 @@ endif::git-pull[] behavior for a remote may be specified with the remote.<name>.tagOpt setting. See linkgit:git-config[1]. -ifndef::git-pull[] --refmap=<refspec>:: When fetching refs listed on the command line, use the specified refspec (can be given more than once) to map the refs to remote-tracking branches, instead of the values of `remote.*.fetch` configuration variables for the remote - repository. See section on "Configured Remote-tracking + repository. Providing an empty `<refspec>` to the + `--refmap` option causes Git to ignore the configured + refspecs and rely entirely on the refspecs supplied as + command-line arguments. See section on "Configured Remote-tracking Branches" for details. -t:: @@ -143,6 +182,7 @@ ifndef::git-pull[] is used (though tags may be pruned anyway if they are also the destination of an explicit refspec; see `--prune`). +ifndef::git-pull[] --recurse-submodules[=yes|on-demand|no]:: This option controls if and under what conditions new commits of populated submodules should be fetched too. It can be used as a @@ -152,19 +192,36 @@ ifndef::git-pull[] value. Use 'on-demand' to only recurse into a populated submodule when the superproject retrieves a commit that updates the submodule's reference to a commit that isn't already in the local submodule - clone. + clone. By default, 'on-demand' is used, unless + `fetch.recurseSubmodules` is set (see linkgit:git-config[1]). +endif::git-pull[] -j:: --jobs=<n>:: - Number of parallel children to be used for fetching submodules. - Each will fetch from different submodules, such that fetching many - submodules will be faster. By default submodules will be fetched - one at a time. + Number of parallel children to be used for all forms of fetching. ++ +If the `--multiple` option was specified, the different remotes will be fetched +in parallel. If multiple submodules are fetched, they will be fetched in +parallel. To control them independently, use the config settings +`fetch.parallel` and `submodule.fetchJobs` (see linkgit:git-config[1]). ++ +Typically, parallel recursive and multi-remote fetches will be faster. By +default fetches are performed sequentially, not in parallel. +ifndef::git-pull[] --no-recurse-submodules:: Disable recursive fetching of submodules (this has the same effect as using the `--recurse-submodules=no` option). +endif::git-pull[] +--set-upstream:: + If the remote is fetched successfully, add upstream + (tracking) reference, used by argument-less + linkgit:git-pull[1] and other commands. For more information, + see `branch.<name>.merge` and `branch.<name>.remote` in + linkgit:git-config[1]. + +ifndef::git-pull[] --submodule-prefix=<path>:: Prepend <path> to paths printed in informative messages such as "Fetching submodule foo". This option is used @@ -177,7 +234,6 @@ ifndef::git-pull[] recursion (such as settings in linkgit:gitmodules[5] and linkgit:git-config[1]) override this option, as does specifying --[no-]recurse-submodules directly. -endif::git-pull[] -u:: --update-head-ok:: @@ -187,6 +243,7 @@ endif::git-pull[] to communicate with 'git fetch', and unless you are implementing your own Porcelain you are not supposed to use it. +endif::git-pull[] --upload-pack <upload-pack>:: When given, and the repository to fetch from is handled @@ -221,6 +278,19 @@ endif::git-pull[] When multiple `--server-option=<option>` are given, they are all sent to the other side in the order listed on the command line. +--show-forced-updates:: + By default, git checks if a branch is force-updated during + fetch. This can be disabled through fetch.showForcedUpdates, but + the --show-forced-updates option guarantees this check occurs. + See linkgit:git-config[1]. + +--no-show-forced-updates:: + By default, git checks if a branch is force-updated during + fetch. Pass --no-show-forced-updates or set fetch.showForcedUpdates + to false to skip this check for performance reasons. If used during + 'git-pull' the --ff-only option will still check for forced updates + before attempting a fast-forward update. See linkgit:git-config[1]. + -4:: --ipv4:: Use IPv4 addresses only, ignoring IPv6 addresses. diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 8b0e4c7fa8..be5e3ac54b 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -11,7 +11,8 @@ SYNOPSIS 'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize] - [--chmod=(+|-)x] [--] [<pathspec>...] + [--chmod=(+|-)x] [--pathspec-from-file=<file> [--pathspec-file-nul]] + [--] [<pathspec>...] DESCRIPTION ----------- @@ -187,6 +188,19 @@ for "git add --no-all <pathspec>...", i.e. ignored removed files. bit is only changed in the index, the files on disk are left unchanged. +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + \--:: This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index fc3b993c33..8714dfcb76 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -15,8 +15,9 @@ SYNOPSIS [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>] [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>] + [--quoted-cr=<action>] [(<mbox> | <Maildir>)...] -'git am' (--continue | --skip | --abort | --quit | --show-current-patch) +'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)]) DESCRIPTION ----------- @@ -33,7 +34,7 @@ OPTIONS -s:: --signoff:: - Add a `Signed-off-by:` line to the commit message, using + Add a `Signed-off-by` trailer to the commit message, using the committer identity of yourself. See the signoff option in linkgit:git-commit[1] for more information. @@ -59,6 +60,9 @@ OPTIONS --no-scissors:: Ignore scissors lines (see linkgit:git-mailinfo[1]). +--quoted-cr=<action>:: + This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]). + -m:: --message-id:: Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]), @@ -79,7 +83,7 @@ OPTIONS Pass `-u` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]). The proposed commit log message taken from the e-mail is re-coded into UTF-8 encoding (configuration variable - `i18n.commitencoding` can be used to specify project's + `i18n.commitEncoding` can be used to specify project's preferred encoding if it is not UTF-8). + This was optional in prior versions of git, but now it is the @@ -148,9 +152,12 @@ default. You can use `--no-utf8` to override this. -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand both `commit.gpgSign` configuration variable, and + earlier `--gpg-sign`. --continue:: -r:: @@ -176,9 +183,11 @@ default. You can use `--no-utf8` to override this. Abort the patching operation but keep HEAD and the index untouched. ---show-current-patch:: - Show the patch being applied when "git am" is stopped because - of conflicts. +--show-current-patch[=(diff|raw)]:: + Show the message at which `git am` has stopped due to + conflicts. If `raw` is specified, show the raw contents of + the e-mail message; if `diff`, show the diff portion only. + Defaults to `raw`. DISCUSSION ---------- @@ -190,8 +199,8 @@ the commit, after stripping common prefix "[PATCH <anything>]". The "Subject: " line is supposed to concisely describe what the commit is about in one line of text. -"From: " and "Subject: " lines starting the body override the respective -commit author name and title values taken from the headers. +"From: ", "Date: ", and "Subject: " lines starting the body override the +respective commit author name and title values taken from the headers. The commit message is formed by the title taken from the "Subject: ", a blank line and the body of the message up to diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index b9aa39000f..aa1ae56a25 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -61,18 +61,18 @@ OPTIONS file and detects errors. Turns off "apply". --index:: - When `--check` is in effect, or when applying the patch - (which is the default when none of the options that - disables it is in effect), make sure the patch is - applicable to what the current index file records. If - the file to be patched in the working tree is not - up to date, it is flagged as an error. This flag also - causes the index file to be updated. + Apply the patch to both the index and the working tree (or + merely check that it would apply cleanly to both if `--check` is + in effect). Note that `--index` expects index entries and + working tree copies for relevant paths to be identical (their + contents and metadata such as file mode must match), and will + raise an error if they are not, even if the patch would apply + cleanly to both the index and the working tree in isolation. --cached:: - Apply a patch without touching the working tree. Instead take the - cached data, apply the patch, and store the result in the index - without using the working tree. This implies `--index`. + Apply the patch to just the index, without touching the working + tree. If `--check` is in effect, merely check that it would + apply cleanly to the index entry. --intent-to-add:: When applying the patch only to the working tree, mark new @@ -84,12 +84,13 @@ OPTIONS -3:: --3way:: - When the patch does not apply cleanly, fall back on 3-way merge if - the patch records the identity of blobs it is supposed to apply to, - and we have those blobs available locally, possibly leaving the + Attempt 3-way merge if the patch records the identity of blobs it is supposed + to apply to and we have those blobs available locally, possibly leaving the conflict markers in the files in the working tree for the user to - resolve. This option implies the `--index` option, and is incompatible - with the `--reject` and the `--cached` options. + resolve. This option implies the `--index` option unless the + `--cached` option is used, and is incompatible with the `--reject` option. + When used with the `--cached` option, any conflicts are left at higher stages + in the cache. --build-fake-ancestor=<file>:: Newer 'git diff' output has embedded 'index information' diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index cfa1e4ebe4..9f8172828d 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -55,6 +55,12 @@ OPTIONS --output=<file>:: Write the archive to <file> instead of stdout. +--add-file=<file>:: + Add a non-tracked file to the archive. Can be repeated to add + multiple files. The path of the file in the archive is built + by concatenating the value for `--prefix` (if any) and the + basename of <file>. + --worktree-attributes:: Look for attributes in .gitattributes files in the working tree as well (see <<ATTRIBUTES>>). diff --git a/Documentation/git-bisect-lk2009.txt b/Documentation/git-bisect-lk2009.txt index e99925184d..f3d9566c89 100644 --- a/Documentation/git-bisect-lk2009.txt +++ b/Documentation/git-bisect-lk2009.txt @@ -158,7 +158,7 @@ Test suites are very nice. But when they are used alone, they are supposed to be used so that all the tests are checked after each commit. This means that they are not very efficient, because many tests are run for no interesting result, and they suffer from -combinational explosion. +combinatorial explosion. In fact the problem is that big software often has many different configuration options and that each test case should pass for each @@ -473,7 +473,7 @@ Z-Z ------------- 2) starting from the "good" ends of the graph, associate to each -commit the number of ancestors it has plus one + commit the number of ancestors it has plus one For example with the following graph where H is the "bad" commit and A and D are some parents of some "good" commits: @@ -514,7 +514,7 @@ D---E ------------- 4) the best bisection point is the commit with the highest associated -number + number So in the above example the best bisection point is commit C. @@ -580,8 +580,8 @@ good or a bad commit does not give more or less information). Let's also suppose that we have a cleaned up graph like one after step 1) in the bisection algorithm above. This means that we can measure -the information we get in terms of number of commit we can remove from -the graph.. + the information we get in terms of number of commit we can remove + from the graph.. And let's take a commit X in the graph. @@ -689,18 +689,18 @@ roughly the following steps: 6) sort the commit by decreasing associated value 7) if the first commit has not been skipped, we can return it and stop -here + here 8) otherwise filter out all the skipped commits in the sorted list 9) use a pseudo random number generator (PRNG) to generate a random -number between 0 and 1 + number between 0 and 1 10) multiply this random number with its square root to bias it toward -0 + 0 11) multiply the result by the number of commits in the filtered list -to get an index into this list + to get an index into this list 12) return the commit at the computed index @@ -1350,9 +1350,9 @@ References - [[[1]]] https://www.nist.gov/sites/default/files/documents/director/planning/report02-3.pdf['The Economic Impacts of Inadequate Infratructure for Software Testing'. Nist Planning Report 02-3], see Executive Summary and Chapter 8. - [[[2]]] http://www.oracle.com/technetwork/java/codeconvtoc-136057.html['Code Conventions for the Java Programming Language'. Sun Microsystems.] - [[[3]]] https://en.wikipedia.org/wiki/Software_maintenance['Software maintenance'. Wikipedia.] -- [[[4]]] https://public-inbox.org/git/7vps5xsbwp.fsf_-_@assigned-by-dhcp.cox.net/[Junio C Hamano. 'Automated bisect success story'.] +- [[[4]]] https://lore.kernel.org/git/7vps5xsbwp.fsf_-_@assigned-by-dhcp.cox.net/[Junio C Hamano. 'Automated bisect success story'.] - [[[5]]] https://lwn.net/Articles/317154/[Christian Couder. 'Fully automated bisecting with "git bisect run"'. LWN.net.] - [[[6]]] https://lwn.net/Articles/277872/[Jonathan Corbet. 'Bisection divides users and developers'. LWN.net.] -- [[[7]]] http://marc.info/?l=linux-kernel&m=119702753411680&w=2[Ingo Molnar. 'Re: BUG 2.6.23-rc3 can't see sd partitions on Alpha'. Linux-kernel mailing list.] +- [[[7]]] https://lore.kernel.org/lkml/20071207113734.GA14598@elte.hu/[Ingo Molnar. 'Re: BUG 2.6.23-rc3 can't see sd partitions on Alpha'. Linux-kernel mailing list.] - [[[8]]] https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html[Junio C Hamano and the git-list. 'git-bisect(1) Manual Page'. Linux Kernel Archives.] - [[[9]]] https://github.com/Ealdwulf/bbchop[Ealdwulf. 'bbchop'. GitHub.] diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 4b45d837a7..fbb39fbdf5 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -16,8 +16,8 @@ DESCRIPTION The command takes various subcommands, and different options depending on the subcommand: - git bisect start [--term-{old,good}=<term> --term-{new,bad}=<term>] - [--no-checkout] [<bad> [<good>...]] [--] [<paths>...] + git bisect start [--term-{new,bad}=<term> --term-{old,good}=<term>] + [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...] git bisect (bad|new|<term-new>) [<rev>] git bisect (good|old|<term-old>) [<rev>...] git bisect terms [--term-good | --term-bad] @@ -365,6 +365,17 @@ does not require a checked out tree. + If the repository is bare, `--no-checkout` is assumed. +--first-parent:: ++ +Follow only the first parent commit upon seeing a merge commit. ++ +In detecting regressions introduced through the merging of a branch, the merge +commit will be identified as introduction of the bug and its ancestors will be +ignored. ++ +This option is particularly useful in avoiding false positives when a merged +branch contained broken or non-buildable commits, but the merge itself was OK. + EXAMPLES -------- @@ -413,7 +424,7 @@ $ cat ~/test.sh # tweak the working tree by merging the hot-fix branch # and then attempt a build -if git merge --no-commit hot-fix && +if git merge --no-commit --no-ff hot-fix && make then # run project specific test and report its status diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index 16323eb80e..3bf5d5d8b4 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -10,6 +10,7 @@ SYNOPSIS [verse] 'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] + [--ignore-rev <rev>] [--ignore-revs-file <file>] [--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>..<rev>] [--] <file> @@ -86,7 +87,9 @@ include::blame-options.txt[] --abbrev=<n>:: Instead of using the default 7+1 hexadecimal digits as the - abbreviated object name, use <n>+1 digits. Note that 1 column + abbreviated object name, use <m>+1 digits, where <m> is at + least <n> but ensures the commit object names are unique. + Note that 1 column is used for a caret to mark the boundary commit. @@ -223,7 +226,7 @@ commit commentary), a blame viewer will not care. MAPPING AUTHORS --------------- -include::mailmap.txt[] +See linkgit:gitmailmap[5]. SEE ALSO diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index d9325e2145..94dc9a54f2 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -8,12 +8,11 @@ git-branch - List, create, or delete branches SYNOPSIS -------- [verse] -'git branch' [--color[=<when>] | --no-color] - [-v [--abbrev=<length> | --no-abbrev]] - [--show-current] +'git branch' [--color[=<when>] | --no-color] [--show-current] + [-v [--abbrev=<n> | --no-abbrev]] [--column[=<options>] | --no-column] [--sort=<key>] - [(--merged | --no-merged) [<commit>]] - [--contains [<commit]] [--no-contains [<commit>]] + [--merged [<commit>]] [--no-merged [<commit>]] + [--contains [<commit>]] [--no-contains [<commit>]] [--points-at <object>] [--format=<format>] [(-r | --remotes) | (-a | --all)] [--list] [<pattern>...] @@ -29,8 +28,10 @@ DESCRIPTION ----------- If `--list` is given, or if there are no non-option arguments, existing -branches are listed; the current branch will be highlighted with an -asterisk. Option `-r` causes the remote-tracking branches to be listed, +branches are listed; the current branch will be highlighted in green and +marked with an asterisk. Any branches checked out in linked worktrees will +be highlighted in cyan and marked with a plus sign. Option `-r` causes the +remote-tracking branches to be listed, and option `-a` shows both local and remote branches. If a `<pattern>` @@ -59,7 +60,7 @@ can leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. Note that this will create the new branch, but it will not switch the -working tree to it; use "git checkout <newbranch>" to switch to the +working tree to it; use "git switch <newbranch>" to switch to the new branch. When a local branch is started off a remote-tracking branch, Git sets up the @@ -77,8 +78,8 @@ renaming. If <newbranch> exists, -M must be used to force the rename to happen. The `-c` and `-C` options have the exact same semantics as `-m` and -`-M`, except instead of the branch being renamed it along with its -config and reflog will be copied to a new name. +`-M`, except instead of the branch being renamed, it will be copied to a +new name, along with its config and reflog. With a `-d` or `-D` option, `<branchname>` will be deleted. You may specify more than one branch for deletion. If the branch currently @@ -152,7 +153,7 @@ OPTIONS --column[=<options>]:: --no-column:: Display branch listing in columns. See configuration variable - column.branch for option syntax.`--column` and `--no-column` + `column.branch` for option syntax. `--column` and `--no-column` without options are equivalent to 'always' and 'never' respectively. + This option is only applicable in non-verbose mode. @@ -183,16 +184,20 @@ This option is only applicable in non-verbose mode. When in list mode, show sha1 and commit subject line for each head, along with relationship to upstream branch (if any). If given twice, print - the name of the upstream branch, as well (see also `git remote - show <remote>`). + the path of the linked worktree (if any) and the name of the upstream + branch, as well (see also `git remote show <remote>`). Note that the + current worktree's HEAD will not have its path printed (it will always + be your current directory). -q:: --quiet:: Be more quiet when creating or deleting a branch, suppressing non-error messages. ---abbrev=<length>:: - Alter the sha1's minimum display length in the output listing. +--abbrev=<n>:: + In the verbose listing that show the commit object name, + show the shortest prefix that is at least '<n>' hexdigits + long that uniquely refers the object. The default value is 7 and can be overridden by the `core.abbrev` config option. @@ -211,7 +216,7 @@ This option is only applicable in non-verbose mode. + This behavior is the default when the start point is a remote-tracking branch. Set the branch.autoSetupMerge configuration variable to `false` if you -want `git checkout` and `git branch` to always behave as if `--no-track` +want `git switch`, `git checkout` and `git branch` to always behave as if `--no-track` were given. Set it to `always` if you want this behavior when the start-point is either a local or remote-tracking branch. @@ -249,13 +254,11 @@ start-point is either a local or remote-tracking branch. --merged [<commit>]:: Only list branches whose tips are reachable from the - specified commit (HEAD if not specified). Implies `--list`, - incompatible with `--no-merged`. + specified commit (HEAD if not specified). Implies `--list`. --no-merged [<commit>]:: Only list branches whose tips are not reachable from the - specified commit (HEAD if not specified). Implies `--list`, - incompatible with `--merged`. + specified commit (HEAD if not specified). Implies `--list`. <branchname>:: The name of the branch to create or delete. @@ -310,7 +313,7 @@ Start development from a known tag:: $ git clone git://git.kernel.org/pub/scm/.../linux-2.6 my2.6 $ cd my2.6 $ git branch my2.6.14 v2.6.14 <1> -$ git checkout my2.6.14 +$ git switch my2.6.14 ------------ + <1> This step and the next one could be combined into a single step with @@ -347,9 +350,9 @@ Patterns will normally need quoting. NOTES ----- -If you are creating a branch that you want to checkout immediately, it is -easier to use the git checkout command with its `-b` option to create -a branch and check it out with a single command. +If you are creating a branch that you want to switch to immediately, +it is easier to use the "git switch" command with its `-c` option to +do the same thing with a single command. The options `--contains`, `--no-contains`, `--merged` and `--no-merged` serve four related but different purposes: @@ -367,6 +370,8 @@ serve four related but different purposes: - `--no-merged` is used to find branches which are candidates for merging into HEAD, since those branches are not fully contained by HEAD. +include::ref-reachability-filters.txt[] + SEE ALSO -------- linkgit:git-check-ref-format[1], diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt new file mode 100644 index 0000000000..66e88c2e31 --- /dev/null +++ b/Documentation/git-bugreport.txt @@ -0,0 +1,54 @@ +git-bugreport(1) +================ + +NAME +---- +git-bugreport - Collect information for user to file a bug report + +SYNOPSIS +-------- +[verse] +'git bugreport' [(-o | --output-directory) <path>] [(-s | --suffix) <format>] + +DESCRIPTION +----------- +Captures information about the user's machine, Git client, and repository state, +as well as a form requesting information about the behavior the user observed, +into a single text file which the user can then share, for example to the Git +mailing list, in order to report an observed bug. + +The following information is requested from the user: + + - Reproduction steps + - Expected behavior + - Actual behavior + +The following information is captured automatically: + + - 'git version --build-options' + - uname sysname, release, version, and machine strings + - Compiler-specific info string + - A list of enabled hooks + - $SHELL + +This tool is invoked via the typical Git setup process, which means that in some +cases, it might not be able to launch - for example, if a relevant config file +is unreadable. In this kind of scenario, it may be helpful to manually gather +the kind of information listed above when manually asking for help. + +OPTIONS +------- +-o <path>:: +--output-directory <path>:: + Place the resulting bug report file in `<path>` instead of the root of + the Git repository. + +-s <format>:: +--suffix <format>:: + Specify an alternate suffix for the bugreport name, to create a file + named 'git-bugreport-<formatted suffix>'. This should take the form of a + strftime(3) format string; the current local time will be used. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt index 7d6c9dcd17..ac0d003835 100644 --- a/Documentation/git-bundle.txt +++ b/Documentation/git-bundle.txt @@ -9,33 +9,66 @@ git-bundle - Move objects and refs by archive SYNOPSIS -------- [verse] -'git bundle' create <file> <git-rev-list-args> -'git bundle' verify <file> +'git bundle' create [-q | --quiet | --progress | --all-progress] [--all-progress-implied] + [--version=<version>] <file> <git-rev-list-args> +'git bundle' verify [-q | --quiet] <file> 'git bundle' list-heads <file> [<refname>...] 'git bundle' unbundle <file> [<refname>...] DESCRIPTION ----------- -Some workflows require that one or more branches of development on one -machine be replicated on another machine, but the two machines cannot -be directly connected, and therefore the interactive Git protocols (git, -ssh, http) cannot be used. This command provides support for -'git fetch' and 'git pull' to operate by packaging objects and references -in an archive at the originating machine, then importing those into -another repository using 'git fetch' and 'git pull' -after moving the archive by some means (e.g., by sneakernet). As no -direct connection between the repositories exists, the user must specify a -basis for the bundle that is held by the destination repository: the -bundle assumes that all objects in the basis are already in the -destination repository. +Create, unpack, and manipulate "bundle" files. Bundles are used for +the "offline" transfer of Git objects without an active "server" +sitting on the other side of the network connection. + +They can be used to create both incremental and full backups of a +repository, and to relay the state of the references in one repository +to another. + +Git commands that fetch or otherwise "read" via protocols such as +`ssh://` and `https://` can also operate on bundle files. It is +possible linkgit:git-clone[1] a new repository from a bundle, to use +linkgit:git-fetch[1] to fetch from one, and to list the references +contained within it with linkgit:git-ls-remote[1]. There's no +corresponding "write" support, i.e.a 'git push' into a bundle is not +supported. + +See the "EXAMPLES" section below for examples of how to use bundles. + +BUNDLE FORMAT +------------- + +Bundles are `.pack` files (see linkgit:git-pack-objects[1]) with a +header indicating what references are contained within the bundle. + +Like the the packed archive format itself bundles can either be +self-contained, or be created using exclusions. +See the "OBJECT PREREQUISITES" section below. + +Bundles created using revision exclusions are "thin packs" created +using the `--thin` option to linkgit:git-pack-objects[1], and +unbundled using the `--fix-thin` option to linkgit:git-index-pack[1]. + +There is no option to create a "thick pack" when using revision +exclusions, users should not be concerned about the difference. By +using "thin packs" bundles created using exclusions are smaller in +size. That they're "thin" under the hood is merely noted here as a +curiosity, and as a reference to other documentation + +See link:technical/bundle-format.html[the `bundle-format` +documentation] for more details and the discussion of "thin pack" in +link:technical/pack-format.html[the pack format documentation] for +further details. OPTIONS ------- -create <file>:: +create [options] <file> <git-rev-list-args>:: Used to create a bundle named 'file'. This requires the - 'git-rev-list-args' arguments to define the bundle contents. + '<git-rev-list-args>' arguments to define the bundle contents. + 'options' contains the options specific to the 'git bundle create' + subcommand. verify <file>:: Used to check that a bundle file is valid and will apply @@ -75,23 +108,124 @@ unbundle <file>:: necessarily everything in the pack (in this case, 'git bundle' acts like 'git fetch-pack'). +--progress:: + Progress status is reported on the standard error stream + by default when it is attached to a terminal, unless -q + is specified. This flag forces progress status even if + the standard error stream is not directed to a terminal. + +--all-progress:: + When --stdout is specified then progress report is + displayed during the object count and compression phases + but inhibited during the write-out phase. The reason is + that in some cases the output stream is directly linked + to another command which may wish to display progress + status of its own as it processes incoming pack data. + This flag is like --progress except that it forces progress + report for the write-out phase as well even if --stdout is + used. + +--all-progress-implied:: + This is used to imply --all-progress whenever progress display + is activated. Unlike --all-progress this flag doesn't actually + force any progress display by itself. + +--version=<version>:: + Specify the bundle version. Version 2 is the older format and can only be + used with SHA-1 repositories; the newer version 3 contains capabilities that + permit extensions. The default is the oldest supported format, based on the + hash algorithm in use. + +-q:: +--quiet:: + This flag makes the command not to report its progress + on the standard error stream. + SPECIFYING REFERENCES --------------------- -'git bundle' will only package references that are shown by -'git show-ref': this includes heads, tags, and remote heads. References -such as `master~1` cannot be packaged, but are perfectly suitable for -defining the basis. More than one reference may be packaged, and more -than one basis can be specified. The objects packaged are those not -contained in the union of the given bases. Each basis can be -specified explicitly (e.g. `^master~10`), or implicitly (e.g. -`master~10..master`, `--since=10.days.ago master`). +Revisions must accompanied by reference names to be packaged in a +bundle. + +More than one reference may be packaged, and more than one set of prerequisite objects can +be specified. The objects packaged are those not contained in the +union of the prerequisites. + +The 'git bundle create' command resolves the reference names for you +using the same rules as `git rev-parse --abbrev-ref=loose`. Each +prerequisite can be specified explicitly (e.g. `^master~10`), or implicitly +(e.g. `master~10..master`, `--since=10.days.ago master`). + +All of these simple cases are OK (assuming we have a "master" and +"next" branch): + +---------------- +$ git bundle create master.bundle master +$ echo master | git bundle create master.bundle --stdin +$ git bundle create master-and-next.bundle master next +$ (echo master; echo next) | git bundle create master-and-next.bundle --stdin +---------------- + +And so are these (and the same but omitted `--stdin` examples): + +---------------- +$ git bundle create recent-master.bundle master~10..master +$ git bundle create recent-updates.bundle master~10..master next~5..next +---------------- + +A revision name or a range whose right-hand-side cannot be resolved to +a reference is not accepted: + +---------------- +$ git bundle create HEAD.bundle $(git rev-parse HEAD) +fatal: Refusing to create empty bundle. +$ git bundle create master-yesterday.bundle master~10..master~5 +fatal: Refusing to create empty bundle. +---------------- + +OBJECT PREREQUISITES +-------------------- + +When creating bundles it is possible to create a self-contained bundle +that can be unbundled in a repository with no common history, as well +as providing negative revisions to exclude objects needed in the +earlier parts of the history. + +Feeding a revision such as `new` to `git bundle create` will create a +bundle file that contains all the objects reachable from the revision +`new`. That bundle can be unbundled in any repository to obtain a full +history that leads to the revision `new`: + +---------------- +$ git bundle create full.bundle new +---------------- + +A revision range such as `old..new` will produce a bundle file that +will require the revision `old` (and any objects reachable from it) +to exist for the bundle to be "unbundle"-able: + +---------------- +$ git bundle create full.bundle old..new +---------------- + +A self-contained bundle without any prerequisites can be extracted +into anywhere, even into an empty repository, or be cloned from +(i.e., `new`, but not `old..new`). -It is very important that the basis used be held by the destination. It is okay to err on the side of caution, causing the bundle file to contain objects already in the destination, as these are ignored when unpacking at the destination. +If you want to match `git clone --mirror`, which would include your +refs such as `refs/remotes/*`, use `--all`. +If you want to provide the same set of refs that a clone directly +from the source repository would get, use `--branches --tags` for +the `<git-rev-list-args>`. + +The 'git bundle verify' command can be used to check whether your +recipient repository has the required prerequisite commits for a +bundle. + EXAMPLES -------- @@ -102,7 +236,7 @@ but we can move data from A to B via some mechanism (CD, email, etc.). We want to update R2 with development made on the branch master in R1. To bootstrap the process, you can first create a bundle that does not have -any basis. You can use a tag to remember up to what commit you last +any prerequisites. You can use a tag to remember up to what commit you last processed, in order to make it easy to later update the other repository with an incremental bundle: @@ -153,7 +287,7 @@ machineB$ git pull If you know up to what commit the intended recipient repository should have the necessary objects, you can use that knowledge to specify the -basis, giving a cut-off point to limit the revisions and objects that go +prerequisites, giving a cut-off point to limit the revisions and objects that go in the resulting bundle. The previous example used the lastR2bundle tag for this purpose, but you can use any other options that you would give to the linkgit:git-log[1] command. Here are more examples: @@ -164,7 +298,7 @@ You can use a tag that is present in both: $ git bundle create mybundle v1.0.0..master ---------------- -You can use a basis based on time: +You can use a prerequisite based on time: ---------------- $ git bundle create mybundle --since=10.days master @@ -177,7 +311,7 @@ $ git bundle create mybundle -10 master ---------------- You can run `git-bundle verify` to see if you can extract from a bundle -that was created with a basis: +that was created with a prerequisite: ---------------- $ git bundle verify mybundle diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.txt index 8eca671b82..4eb0421b3f 100644 --- a/Documentation/git-cat-file.txt +++ b/Documentation/git-cat-file.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git cat-file' (-t [--allow-unknown-type]| -s [--allow-unknown-type]| -e | -p | <type> | --textconv | --filters ) [--path=<path>] <object> -'git cat-file' (--batch | --batch-check) [ --textconv | --filters ] [--follow-symlinks] +'git cat-file' (--batch[=<format>] | --batch-check[=<format>]) [ --textconv | --filters ] [--follow-symlinks] DESCRIPTION ----------- @@ -35,42 +35,42 @@ OPTIONS -t:: Instead of the content, show the object type identified by - <object>. + `<object>`. -s:: Instead of the content, show the object size identified by - <object>. + `<object>`. -e:: - Exit with zero status if <object> exists and is a valid - object. If <object> is of an invalid format exit with non-zero and + Exit with zero status if `<object>` exists and is a valid + object. If `<object>` is of an invalid format exit with non-zero and emits an error on stderr. -p:: - Pretty-print the contents of <object> based on its type. + Pretty-print the contents of `<object>` based on its type. <type>:: - Typically this matches the real type of <object> but asking + Typically this matches the real type of `<object>` but asking for a type that can trivially be dereferenced from the given - <object> is also permitted. An example is to ask for a - "tree" with <object> being a commit object that contains it, - or to ask for a "blob" with <object> being a tag object that + `<object>` is also permitted. An example is to ask for a + "tree" with `<object>` being a commit object that contains it, + or to ask for a "blob" with `<object>` being a tag object that points at it. --textconv:: Show the content as transformed by a textconv filter. In this case, - <object> has to be of the form <tree-ish>:<path>, or :<path> in + `<object>` has to be of the form `<tree-ish>:<path>`, or `:<path>` in order to apply the filter to the content recorded in the index at - <path>. + `<path>`. --filters:: Show the content as converted by the filters configured in - the current working tree for the given <path> (i.e. smudge filters, - end-of-line conversion, etc). In this case, <object> has to be of - the form <tree-ish>:<path>, or :<path>. + the current working tree for the given `<path>` (i.e. smudge filters, + end-of-line conversion, etc). In this case, `<object>` has to be of + the form `<tree-ish>:<path>`, or `:<path>`. --path=<path>:: - For use with --textconv or --filters, to allow specifying an object + For use with `--textconv` or `--filters`, to allow specifying an object name and a path separately, e.g. when it is difficult to figure out the revision from which the blob came. @@ -115,15 +115,15 @@ OPTIONS repository. --allow-unknown-type:: - Allow -s or -t to query broken/corrupt objects of unknown type. + Allow `-s` or `-t` to query broken/corrupt objects of unknown type. --follow-symlinks:: - With --batch or --batch-check, follow symlinks inside the + With `--batch` or `--batch-check`, follow symlinks inside the repository when requesting objects with extended SHA-1 expressions of the form tree-ish:path-in-tree. Instead of providing output about the link itself, provide output about the linked-to object. If a symlink points outside the - tree-ish (e.g. a link to /foo or a root-level link to ../foo), + tree-ish (e.g. a link to `/foo` or a root-level link to `../foo`), the portion of the link which is outside the tree will be printed. + @@ -175,15 +175,15 @@ respectively print: OUTPUT ------ -If `-t` is specified, one of the <type>. +If `-t` is specified, one of the `<type>`. -If `-s` is specified, the size of the <object> in bytes. +If `-s` is specified, the size of the `<object>` in bytes. -If `-e` is specified, no output, unless the <object> is malformed. +If `-e` is specified, no output, unless the `<object>` is malformed. -If `-p` is specified, the contents of <object> are pretty-printed. +If `-p` is specified, the contents of `<object>` are pretty-printed. -If <type> is specified, the raw (though uncompressed) contents of the <object> +If `<type>` is specified, the raw (though uncompressed) contents of the `<object>` will be returned. BATCH OUTPUT @@ -200,7 +200,7 @@ object, with placeholders of the form `%(atom)` expanded, followed by a newline. The available atoms are: `objectname`:: - The 40-hex object name of the object. + The full hex representation of the object name. `objecttype`:: The type of the object (the same as `cat-file -t` reports). @@ -215,8 +215,9 @@ newline. The available atoms are: `deltabase`:: If the object is stored as a delta on-disk, this expands to the - 40-hex sha1 of the delta base object. Otherwise, expands to the - null sha1 (40 zeroes). See `CAVEATS` below. + full hex representation of the delta base object name. + Otherwise, expands to the null OID (all zeroes). See `CAVEATS` + below. `rest`:: If this atom is used in the output string, input lines are split @@ -235,14 +236,14 @@ newline. For example, `--batch` without a custom format would produce: ------------ -<sha1> SP <type> SP <size> LF +<oid> SP <type> SP <size> LF <contents> LF ------------ Whereas `--batch-check='%(objectname) %(objecttype)'` would produce: ------------ -<sha1> SP <type> LF +<oid> SP <type> LF ------------ If a name is specified on stdin that cannot be resolved to an object in @@ -258,7 +259,7 @@ If a name is specified that might refer to more than one object (an ambiguous sh <object> SP ambiguous LF ------------ -If --follow-symlinks is used, and a symlink in the repository points +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: @@ -267,11 +268,11 @@ symlink SP <size> LF <symlink> LF ------------ -The symlink will either be absolute (beginning with a /), or relative -to the tree root. For instance, if dir/link points to ../../foo, then -<symlink> will be ../foo. <size> is the size of the symlink in bytes. +The symlink will either be absolute (beginning with a `/`), or relative +to the tree root. For instance, if dir/link points to `../../foo`, then +`<symlink>` will be `../foo`. `<size>` is the size of the symlink in bytes. -If --follow-symlinks is used, the following error messages will be +If `--follow-symlinks` is used, the following error messages will be displayed: ------------ diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index 3c0578217b..84f41a8e82 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -32,7 +32,7 @@ OPTIONS instead of from the command-line. -z:: - The output format is modified to be machine-parseable. + The output format is modified to be machine-parsable. If `--stdin` is also given, input paths are separated with a NUL character instead of a linefeed character. diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.txt index 8b42cb3fb2..0c3924a63d 100644 --- a/Documentation/git-check-ignore.txt +++ b/Documentation/git-check-ignore.txt @@ -30,16 +30,22 @@ OPTIONS valid with a single pathname. -v, --verbose:: - Also output details about the matching pattern (if any) - for each given pathname. For precedence rules within and - between exclude sources, see linkgit:gitignore[5]. + Instead of printing the paths that are excluded, for each path + that matches an exclude pattern, print the exclude pattern + together with the path. (Matching an exclude pattern usually + means the path is excluded, but if the pattern begins with '!' + then it is a negated pattern and matching it means the path is + NOT excluded.) ++ +For precedence rules within and between exclude sources, see +linkgit:gitignore[5]. --stdin:: Read pathnames from the standard input, one per line, instead of from the command-line. -z:: - The output format is modified to be machine-parseable (see + The output format is modified to be machine-parsable (see below). If `--stdin` is also given, input paths are separated with a NUL character instead of a linefeed character. diff --git a/Documentation/git-check-mailmap.txt b/Documentation/git-check-mailmap.txt index aa2055dbeb..02f4418323 100644 --- a/Documentation/git-check-mailmap.txt +++ b/Documentation/git-check-mailmap.txt @@ -36,10 +36,17 @@ name is provided or known to the 'mailmap', ``Name $$<user@host>$$'' is printed; otherwise only ``$$<user@host>$$'' is printed. +CONFIGURATION +------------- + +See `mailmap.file` and `mailmap.blob` in linkgit:git-config[1] for how +to specify a custom `.mailmap` target file or object. + + MAPPING AUTHORS --------------- -include::mailmap.txt[] +See linkgit:gitmailmap[5]. GIT diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index d9de992585..ee6a4144fb 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -88,7 +88,8 @@ but it is explicitly forbidden at the beginning of a branch name). When run with `--branch` option in a repository, the input is first expanded for the ``previous checkout syntax'' `@{-n}`. For example, `@{-1}` is a way to refer the last thing that -was checked out using "git checkout" operation. This option should be +was checked out using "git switch" or "git checkout" operation. +This option should be used by porcelains to accept this syntax anywhere a branch name is expected, so they can act as if you typed the branch name. As an exception note that, the ``previous checkout operation'' might result diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 964f912d29..b1a6fe4499 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -12,42 +12,33 @@ SYNOPSIS 'git checkout' [-q] [-f] [-m] --detach [<branch>] 'git checkout' [-q] [-f] [-m] [--detach] <commit> 'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>] -'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>... -'git checkout' [<tree-ish>] [--] <pathspec>... -'git checkout' (-p|--patch) [<tree-ish>] [--] [<paths>...] +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>... +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul] +'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...] DESCRIPTION ----------- Updates files in the working tree to match the version in the index -or the specified tree. If no paths are given, 'git checkout' will +or the specified tree. If no pathspec was given, 'git checkout' will also update `HEAD` to set the specified branch as the current branch. -'git checkout' <branch>:: - To prepare for working on <branch>, switch to it by updating +'git checkout' [<branch>]:: + To prepare for working on `<branch>`, switch to it by updating the index and the files in the working tree, and by pointing - HEAD at the branch. Local modifications to the files in the + `HEAD` at the branch. Local modifications to the files in the working tree are kept, so that they can be committed to the - <branch>. + `<branch>`. + -If <branch> is not found but there does exist a tracking branch in -exactly one remote (call it <remote>) with a matching name, treat as -equivalent to +If `<branch>` is not found but there does exist a tracking branch in +exactly one remote (call it `<remote>`) with a matching name and +`--no-guess` is not specified, treat as equivalent to + ------------ $ git checkout -b <branch> --track <remote>/<branch> ------------ + -If the branch exists in multiple remotes and one of them is named by -the `checkout.defaultRemote` configuration variable, we'll use that -one for the purposes of disambiguation, even if the `<branch>` isn't -unique across all remotes. Set it to -e.g. `checkout.defaultRemote=origin` to always checkout remote -branches from there if `<branch>` is ambiguous but exists on the -'origin' remote. See also `checkout.defaultRemote` in -linkgit:git-config[1]. -+ -You could omit <branch>, in which case the command degenerates to +You could omit `<branch>`, in which case the command degenerates to "check out the current branch", which is a glorified no-op with rather expensive side-effects to show only the tracking information, if exists, for the current branch. @@ -61,7 +52,7 @@ if exists, for the current branch. `--track` without `-b` implies branch creation; see the description of `--track` below. + -If `-B` is given, <new_branch> is created if it doesn't exist; otherwise, it +If `-B` is given, `<new_branch>` is created if it doesn't exist; otherwise, it is reset. This is the transactional equivalent of + ------------ @@ -75,26 +66,27 @@ successful. 'git checkout' --detach [<branch>]:: 'git checkout' [--detach] <commit>:: - Prepare to work on top of <commit>, by detaching HEAD at it + Prepare to work on top of `<commit>`, by detaching `HEAD` at it (see "DETACHED HEAD" section), and updating the index and the files in the working tree. Local modifications to the files in the working tree are kept, so that the resulting working tree will be the state recorded in the commit plus the local modifications. + -When the <commit> argument is a branch name, the `--detach` option can -be used to detach HEAD at the tip of the branch (`git checkout -<branch>` would check out that branch without detaching HEAD). +When the `<commit>` argument is a branch name, the `--detach` option can +be used to detach `HEAD` at the tip of the branch (`git checkout +<branch>` would check out that branch without detaching `HEAD`). + -Omitting <branch> detaches HEAD at the tip of the current branch. +Omitting `<branch>` detaches `HEAD` at the tip of the current branch. -'git checkout' [<tree-ish>] [--] <pathspec>...:: +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...:: +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]:: - Overwrite paths in the working tree by replacing with the - contents in the index or in the <tree-ish> (most often a - commit). When a <tree-ish> is given, the paths that - match the <pathspec> are updated both in the index and in - the working tree. + Overwrite the contents of the files that match the pathspec. + When the `<tree-ish>` (most often a commit) is not given, + overwrite working tree with the contents in the index. + When the `<tree-ish>` is given, overwrite both the index and + the working tree with the contents at the `<tree-ish>`. + The index may contain unmerged entries because of a previous failed merge. By default, if you try to check out such an entry from the index, the @@ -105,12 +97,10 @@ using `--ours` or `--theirs`. With `-m`, changes made to the working tree file can be discarded to re-create the original conflicted merge result. 'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]:: - This is similar to the "check out paths to the working tree - from either the index or from a tree-ish" mode described - above, but lets you use the interactive interface to show - the "diff" output and choose which hunks to use in the - result. See below for the description of `--patch` option. - + This is similar to the previous mode, but lets you use the + interactive interface to show the "diff" output and choose which + hunks to use in the result. See below for the description of + `--patch` option. OPTIONS ------- @@ -118,7 +108,8 @@ OPTIONS --quiet:: Quiet, suppress feedback messages. ---[no-]progress:: +--progress:: +--no-progress:: Progress status is reported on the standard error stream by default when it is attached to a terminal, unless `--quiet` is specified. This flag enables progress reporting even if not @@ -127,7 +118,7 @@ OPTIONS -f:: --force:: When switching branches, proceed even if the index or the - working tree differs from HEAD. This is used to throw away + working tree differs from `HEAD`. This is used to throw away local changes. + When checking out paths from the index, do not fail upon unmerged @@ -154,12 +145,12 @@ on your side branch as `theirs` (i.e. "one contributor's work on top of it"). -b <new_branch>:: - Create a new branch named <new_branch> and start it at - <start_point>; see linkgit:git-branch[1] for details. + Create a new branch named `<new_branch>` and start it at + `<start_point>`; see linkgit:git-branch[1] for details. -B <new_branch>:: - Creates the branch <new_branch> and start it at <start_point>; - if it already exists, then reset it to <start_point>. This is + Creates the branch `<new_branch>` and start it at `<start_point>`; + if it already exists, then reset it to `<start_point>`. This is equivalent to running "git branch" with "-f"; see linkgit:git-branch[1] for details. @@ -172,38 +163,63 @@ If no `-b` option is given, the name of the new branch will be derived from the remote-tracking branch, by looking at the local part of the refspec configured for the corresponding remote, and then stripping the initial part up to the "*". -This would tell us to use "hack" as the local branch when branching -off of "origin/hack" (or "remotes/origin/hack", or even -"refs/remotes/origin/hack"). If the given name has no slash, or the above +This would tell us to use `hack` as the local branch when branching +off of `origin/hack` (or `remotes/origin/hack`, or even +`refs/remotes/origin/hack`). If the given name has no slash, or the above guessing results in an empty name, the guessing is aborted. You can explicitly give a name with `-b` in such a case. --no-track:: Do not set up "upstream" configuration, even if the - branch.autoSetupMerge configuration variable is true. + `branch.autoSetupMerge` configuration variable is true. + +--guess:: +--no-guess:: + If `<branch>` is not found but there does exist a tracking + branch in exactly one remote (call it `<remote>`) with a + matching name, treat as equivalent to ++ +------------ +$ git checkout -b <branch> --track <remote>/<branch> +------------ ++ +If the branch exists in multiple remotes and one of them is named by +the `checkout.defaultRemote` configuration variable, we'll use that +one for the purposes of disambiguation, even if the `<branch>` isn't +unique across all remotes. Set it to +e.g. `checkout.defaultRemote=origin` to always checkout remote +branches from there if `<branch>` is ambiguous but exists on the +'origin' remote. See also `checkout.defaultRemote` in +linkgit:git-config[1]. ++ +`--guess` is the default behavior. Use `--no-guess` to disable it. ++ +The default behavior can be set via the `checkout.guess` configuration +variable. -l:: Create the new branch's reflog; see linkgit:git-branch[1] for details. +-d:: --detach:: Rather than checking out a branch to work on it, check out a commit for inspection and discardable experiments. - This is the default behavior of "git checkout <commit>" when - <commit> is not a branch name. See the "DETACHED HEAD" section + This is the default behavior of `git checkout <commit>` when + `<commit>` is not a branch name. See the "DETACHED HEAD" section below for details. --orphan <new_branch>:: - Create a new 'orphan' branch, named <new_branch>, started from - <start_point> and switch to it. The first commit made on this + Create a new 'orphan' branch, named `<new_branch>`, started from + `<start_point>` and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits. + The index and the working tree are adjusted as if you had previously run -"git checkout <start_point>". This allows you to start a new history -that records a set of paths similar to <start_point> by easily running -"git commit -a" to make the root commit. +`git checkout <start_point>`. This allows you to start a new history +that records a set of paths similar to `<start_point>` by easily running +`git commit -a` to make the root commit. + This can be useful when you want to publish the tree from a commit without exposing its full history. You might want to do this to publish @@ -212,17 +228,17 @@ whose full history contains proprietary or otherwise encumbered bits of code. + If you want to start a disconnected history that records a set of paths -that is totally different from the one of <start_point>, then you should +that is totally different from the one of `<start_point>`, then you should clear the index and the working tree right after creating the orphan -branch by running "git rm -rf ." from the top level of the working tree. +branch by running `git rm -rf .` from the top level of the working tree. Afterwards you will be ready to prepare your new files, repopulating the working tree, by copying them from elsewhere, extracting a tarball, etc. --ignore-skip-worktree-bits:: In sparse checkout mode, `git checkout -- <paths>` would - update only entries matched by <paths> and sparse patterns - in $GIT_DIR/info/sparse-checkout. This option ignores - the sparse patterns and adds back any files in <paths>. + update only entries matched by `<paths>` and sparse patterns + in `$GIT_DIR/info/sparse-checkout`. This option ignores + the sparse patterns and adds back any files in `<paths>`. -m:: --merge:: @@ -246,25 +262,25 @@ the conflicted merge in the specified paths. When switching branches with `--merge`, staged changes may be lost. --conflict=<style>:: - The same as --merge option above, but changes the way the + The same as `--merge` option above, but changes the way the conflicting hunks are presented, overriding the - merge.conflictStyle configuration variable. Possible values are + `merge.conflictStyle` configuration variable. Possible values are "merge" (default) and "diff3" (in addition to what is shown by "merge" style, shows the original contents). -p:: --patch:: Interactively select hunks in the difference between the - <tree-ish> (or the index, if unspecified) and the working + `<tree-ish>` (or the index, if unspecified) and the working tree. The chosen hunks are then applied in reverse to the - working tree (and if a <tree-ish> was specified, the index). + working tree (and if a `<tree-ish>` was specified, the index). + This means that you can use `git checkout -p` to selectively discard edits from your current working tree. See the ``Interactive Mode'' section of linkgit:git-add[1] to learn how to operate the `--patch` mode. + Note that this option uses the no overlay mode by default (see also -`--[no-]overlay`), and currently doesn't support overlay mode. +`--overlay`), and currently doesn't support overlay mode. --ignore-other-worktrees:: `git checkout` refuses when the wanted ref is already checked @@ -272,38 +288,55 @@ Note that this option uses the no overlay mode by default (see also out anyway. In other words, the ref can be held by more than one worktree. ---[no-]recurse-submodules:: - Using --recurse-submodules will update the content of all initialized +--overwrite-ignore:: +--no-overwrite-ignore:: + Silently overwrite ignored files when switching branches. This + is the default behavior. Use `--no-overwrite-ignore` to abort + the operation when the new branch contains ignored files. + +--recurse-submodules:: +--no-recurse-submodules:: + Using `--recurse-submodules` will update the content of all active submodules according to the commit recorded in the superproject. If local modifications in a submodule would be overwritten the checkout - will fail unless `-f` is used. If nothing (or --no-recurse-submodules) - is used, the work trees of submodules will not be updated. - Just like linkgit:git-submodule[1], this will detach the - submodules HEAD. + will fail unless `-f` is used. If nothing (or `--no-recurse-submodules`) + is used, submodules working trees will not be updated. + Just like linkgit:git-submodule[1], this will detach `HEAD` of the + submodule. ---no-guess:: - Do not attempt to create a branch if a remote tracking branch - of the same name exists. - ---[no-]overlay:: +--overlay:: +--no-overlay:: In the default overlay mode, `git checkout` never removes files from the index or the working tree. When specifying `--no-overlay`, files that appear in the index and - working tree, but not in <tree-ish> are removed, to make them - match <tree-ish> exactly. + working tree, but not in `<tree-ish>` are removed, to make them + match `<tree-ish>` exactly. + +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). <branch>:: Branch to checkout; if it refers to a branch (i.e., a name that, when prepended with "refs/heads/", is a valid ref), then that branch is checked out. Otherwise, if it refers to a valid - commit, your HEAD becomes "detached" and you are no longer on + commit, your `HEAD` becomes "detached" and you are no longer on any branch (see below for details). + -You can use the `"@{-N}"` syntax to refer to the N-th last +You can use the `@{-N}` syntax to refer to the N-th last branch/commit checked out using "git checkout" operation. You may -also specify `-` which is synonymous to `"@{-1}"`. +also specify `-` which is synonymous to `@{-1}`. + -As a special case, you may use `"A...B"` as a shortcut for the +As a special case, you may use `A...B` as a shortcut for the merge base of `A` and `B` if there is exactly one merge base. You can leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. @@ -312,7 +345,7 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. <start_point>:: The name of a commit at which to start the new branch; see - linkgit:git-branch[1] for details. Defaults to HEAD. + linkgit:git-branch[1] for details. Defaults to `HEAD`. + As a special case, you may use `"A...B"` as a shortcut for the merge base of `A` and `B` if there is exactly one merge base. You can @@ -321,14 +354,24 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. <tree-ish>:: Tree to checkout from (when paths are given). If not specified, the index will be used. ++ +As a special case, you may use `"A...B"` as a shortcut for the +merge base of `A` and `B` if there is exactly one merge base. You can +leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. +\--:: + Do not interpret any more arguments as options. +<pathspec>...:: + Limits the paths affected by the operation. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. DETACHED HEAD ------------- -HEAD normally refers to a named branch (e.g. 'master'). Meanwhile, each +`HEAD` normally refers to a named branch (e.g. `master`). Meanwhile, each branch refers to a specific commit. Let's look at a repo with three -commits, one of them tagged, and with branch 'master' checked out: +commits, one of them tagged, and with branch `master` checked out: ------------ HEAD (refers to branch 'master') @@ -341,10 +384,10 @@ a---b---c branch 'master' (refers to commit 'c') ------------ When a commit is created in this state, the branch is updated to refer to -the new commit. Specifically, 'git commit' creates a new commit 'd', whose -parent is commit 'c', and then updates branch 'master' to refer to new -commit 'd'. HEAD still refers to branch 'master' and so indirectly now refers -to commit 'd': +the new commit. Specifically, 'git commit' creates a new commit `d`, whose +parent is commit `c`, and then updates branch `master` to refer to new +commit `d`. `HEAD` still refers to branch `master` and so indirectly now refers +to commit `d`: ------------ $ edit; git add; git commit @@ -361,7 +404,7 @@ a---b---c---d branch 'master' (refers to commit 'd') It is sometimes useful to be able to checkout a commit that is not at the tip of any named branch, or even to create a new commit that is not referenced by a named branch. Let's look at what happens when we -checkout commit 'b' (here we show two ways this may be done): +checkout commit `b` (here we show two ways this may be done): ------------ $ git checkout v2.0 # or @@ -376,9 +419,9 @@ a---b---c---d branch 'master' (refers to commit 'd') tag 'v2.0' (refers to commit 'b') ------------ -Notice that regardless of which checkout command we use, HEAD now refers -directly to commit 'b'. This is known as being in detached HEAD state. -It means simply that HEAD refers to a specific commit, as opposed to +Notice that regardless of which checkout command we use, `HEAD` now refers +directly to commit `b`. This is known as being in detached `HEAD` state. +It means simply that `HEAD` refers to a specific commit, as opposed to referring to a named branch. Let's see what happens when we create a commit: ------------ @@ -395,7 +438,7 @@ a---b---c---d branch 'master' (refers to commit 'd') tag 'v2.0' (refers to commit 'b') ------------ -There is now a new commit 'e', but it is referenced only by HEAD. We can +There is now a new commit `e`, but it is referenced only by `HEAD`. We can of course add yet another commit in this state: ------------ @@ -413,7 +456,7 @@ a---b---c---d branch 'master' (refers to commit 'd') ------------ In fact, we can perform all the normal Git operations. But, let's look -at what happens when we then checkout master: +at what happens when we then checkout `master`: ------------ $ git checkout master @@ -428,9 +471,9 @@ a---b---c---d branch 'master' (refers to commit 'd') ------------ It is important to realize that at this point nothing refers to commit -'f'. Eventually commit 'f' (and by extension commit 'e') will be deleted +`f`. Eventually commit `f` (and by extension commit `e`) will be deleted by the routine Git garbage collection process, unless we create a reference -before that happens. If we have not yet moved away from commit 'f', +before that happens. If we have not yet moved away from commit `f`, any of these will create a reference to it: ------------ @@ -439,19 +482,19 @@ $ git branch foo <2> $ git tag foo <3> ------------ -<1> creates a new branch 'foo', which refers to commit 'f', and then - updates HEAD to refer to branch 'foo'. In other words, we'll no longer - be in detached HEAD state after this command. +<1> creates a new branch `foo`, which refers to commit `f`, and then + updates `HEAD` to refer to branch `foo`. In other words, we'll no longer + be in detached `HEAD` state after this command. -<2> similarly creates a new branch 'foo', which refers to commit 'f', - but leaves HEAD detached. +<2> similarly creates a new branch `foo`, which refers to commit `f`, + but leaves `HEAD` detached. -<3> creates a new tag 'foo', which refers to commit 'f', - leaving HEAD detached. +<3> creates a new tag `foo`, which refers to commit `f`, + leaving `HEAD` detached. -If we have moved away from commit 'f', then we must first recover its object +If we have moved away from commit `f`, then we must first recover its object name (typically by using git reflog), and then we can create a reference to -it. For example, to see the last two commits to which HEAD referred, we +it. For example, to see the last two commits to which `HEAD` referred, we can use either of these commands: ------------ @@ -462,12 +505,12 @@ $ git log -g -2 HEAD ARGUMENT DISAMBIGUATION ----------------------- -When there is only one argument given and it is not `--` (e.g. "git -checkout abc"), and when the argument is both a valid `<tree-ish>` -(e.g. a branch "abc" exists) and a valid `<pathspec>` (e.g. a file +When there is only one argument given and it is not `--` (e.g. `git +checkout abc`), and when the argument is both a valid `<tree-ish>` +(e.g. a branch `abc` exists) and a valid `<pathspec>` (e.g. a file or a directory whose name is "abc" exists), Git would usually ask you to disambiguate. Because checking out a branch is so common an -operation, however, "git checkout abc" takes "abc" as a `<tree-ish>` +operation, however, `git checkout abc` takes "abc" as a `<tree-ish>` in such a situation. Use `git checkout -- <pathspec>` if you want to checkout these paths out of the index. @@ -475,7 +518,7 @@ EXAMPLES -------- . The following sequence checks out the `master` branch, reverts - the `Makefile` to two revisions back, deletes hello.c by + the `Makefile` to two revisions back, deletes `hello.c` by mistake, and gets it back from the index. + ------------ @@ -487,7 +530,7 @@ $ git checkout hello.c <3> + <1> switch branch <2> take a file out of another commit -<3> restore hello.c from the index +<3> restore `hello.c` from the index + If you want to check out _all_ C source files out of the index, you can say @@ -516,7 +559,7 @@ $ git checkout -- hello.c $ git checkout mytopic ------------ + -However, your "wrong" branch and correct "mytopic" branch may +However, your "wrong" branch and correct `mytopic` branch may differ in files that you have modified locally, in which case the above checkout would fail like this: + @@ -557,6 +600,11 @@ $ edit frotz $ git add frotz ------------ +SEE ALSO +-------- +linkgit:git-switch[1], +linkgit:git-restore[1] + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt index 754b16ce0c..5d750314b2 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.txt @@ -10,9 +10,7 @@ SYNOPSIS [verse] 'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] [-S[<keyid>]] <commit>... -'git cherry-pick' --continue -'git cherry-pick' --quit -'git cherry-pick' --abort +'git cherry-pick' (--continue | --skip | --abort | --quit) DESCRIPTION ----------- @@ -106,14 +104,17 @@ effect to your index in a row. -s:: --signoff:: - Add Signed-off-by line at the end of the commit message. + Add a `Signed-off-by` trailer at the end of the commit message. See the signoff option in linkgit:git-commit[1] for more information. -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand both `commit.gpgSign` configuration variable, and + earlier `--gpg-sign`. --ff:: If the current HEAD is the same as the parent of the diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.txt index db876f7dde..a7f309dff5 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.txt @@ -26,18 +26,20 @@ are affected. OPTIONS ------- -d:: - Remove untracked directories in addition to untracked files. - If an untracked directory is managed by a different Git - repository, it is not removed by default. Use -f option twice - if you really want to remove such a directory. + Normally, when no <path> is specified, git clean will not + recurse into untracked directories to avoid removing too much. + Specify -d to have it recurse into such directories as well. + If any paths are specified, -d is irrelevant; all untracked + files matching the specified paths (with exceptions for nested + git directories mentioned under `--force`) will be removed. -f:: --force:: If the Git configuration variable clean.requireForce is not set to false, 'git clean' will refuse to delete files or directories - unless given -f, -n or -i. Git will refuse to delete directories - with .git sub directory or file unless a second -f - is given. + unless given -f or -i. Git will refuse to modify untracked + nested git repositories (directories with a .git subdirectory) + unless a second -f is given. -i:: --interactive:: @@ -63,7 +65,7 @@ OPTIONS still use the ignore rules given with `-e` options from the command line. This allows removing all untracked files, including build products. This can be used (possibly in - conjunction with 'git reset') to create a pristine + conjunction with 'git restore' or 'git reset') to create a pristine working directory to test a clean build. -X:: diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index ca8871c165..3fe3810f1c 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -15,7 +15,9 @@ SYNOPSIS [--dissociate] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] [--no-tags] [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules] - [--jobs <n>] [--] <repository> [<directory>] + [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow] + [--filter=<filter>] [--] <repository> + [<directory>] DESCRIPTION ----------- @@ -55,6 +57,10 @@ repository is specified as a URL, then this flag is ignored (and we never use the local optimizations). Specifying `--no-local` will override the default when `/path/to/repo` is given, using the regular Git transport instead. ++ +*NOTE*: this operation can race with concurrent modification to the +source repository, similar to running `cp -r src dst` while modifying +`src`. --no-hardlinks:: Force the cloning process from a repository on a local @@ -76,9 +82,9 @@ repository using this option and then delete branches (or use any other Git command that makes any existing commit unreferenced) in the source repository, some objects may become unreferenced (or dangling). These objects may be removed by normal Git operations (such as `git commit`) -which automatically call `git gc --auto`. (See linkgit:git-gc[1].) -If these objects are removed and were referenced by the cloned repository, -then the cloned repository will become corrupt. +which automatically call `git maintenance run --auto`. (See +linkgit:git-maintenance[1].) If these objects are removed and were referenced +by the cloned repository, then the cloned repository will become corrupt. + Note that running `git repack` without the `--local` option in a repository cloned with `--shared` will copy objects from the source repository into a pack @@ -143,6 +149,11 @@ objects from the source repository into a pack in the cloned repository. --no-checkout:: No checkout of HEAD is performed after the clone is complete. +--[no-]reject-shallow:: + Fail if the source repository is a shallow repository. + The 'clone.rejectShallow' configuration variable can be used to + specify the default. + --bare:: Make a 'bare' Git repository. That is, instead of creating `<directory>` and placing the administrative @@ -155,6 +166,22 @@ objects from the source repository into a pack in the cloned repository. used, neither remote-tracking branches nor the related configuration variables are created. +--sparse:: + Initialize the sparse-checkout file so the working + directory starts with only the files in the root + of the repository. The sparse-checkout file can be + modified to grow the working directory as needed. + +--filter=<filter-spec>:: + Use the partial clone feature and request that the server sends + a subset of reachable objects according to a given object filter. + When using `--filter`, the supplied `<filter-spec>` is used for + the partial clone filter. For example, `--filter=blob:none` will + filter out all blobs (file contents) until needed by Git. Also, + `--filter=blob:limit=<size>` will filter out all blobs of size + at least `<size>`. For more details on filter specifications, see + the `--filter` option in linkgit:git-rev-list[1]. + --mirror:: Set up a mirror of the source repository. This implies `--bare`. Compared to `--bare`, `--mirror` not only maps local branches of the @@ -165,8 +192,9 @@ objects from the source repository into a pack in the cloned repository. -o <name>:: --origin <name>:: - Instead of using the remote name `origin` to keep track - of the upstream repository, use `<name>`. + Instead of using the remote name `origin` to keep track of the upstream + repository, use `<name>`. Overrides `clone.defaultRemoteName` from the + config. -b <name>:: --branch <name>:: @@ -241,7 +269,7 @@ maintain a branch with no references other than a single cloned branch. This is useful e.g. to maintain minimal clones of the default branch of some repository for search indexing. ---recurse-submodules[=<pathspec]:: +--recurse-submodules[=<pathspec>]:: After the clone is created, initialize and clone submodules within based on the provided pathspec. If no pathspec is provided, all submodules are initialized and cloned. @@ -260,6 +288,12 @@ or `--mirror` is given) --[no-]shallow-submodules:: All submodules which are cloned will be shallow with a depth of 1. +--[no-]remote-submodules:: + All submodules which are cloned will use the status of the submodule's + remote-tracking branch to update the submodule, rather than the + superproject's recorded SHA-1. Equivalent to passing `--remote` to + `git submodule update`. + --separate-git-dir=<git dir>:: Instead of placing the cloned repository where it is supposed to be, place the cloned repository at the specified directory, diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt index 624470e198..e1f48c95b3 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.txt @@ -9,9 +9,8 @@ git-commit-graph - Write and verify Git commit-graph files SYNOPSIS -------- [verse] -'git commit-graph read' [--object-dir <dir>] -'git commit-graph verify' [--object-dir <dir>] -'git commit-graph write' <options> [--object-dir <dir>] +'git commit-graph verify' [--object-dir <dir>] [--shallow] [--[no-]progress] +'git commit-graph write' <options> [--object-dir <dir>] [--[no-]progress] DESCRIPTION @@ -26,15 +25,23 @@ OPTIONS Use given directory for the location of packfiles and commit-graph file. This parameter exists to specify the location of an alternate that only has the objects directory, not a full `.git` directory. The - commit-graph file is expected to be at `<dir>/info/commit-graph` and - the packfiles are expected to be in `<dir>/pack`. + commit-graph file is expected to be in the `<dir>/info` directory and + the packfiles are expected to be in `<dir>/pack`. If the directory + could not be made into an absolute path, or does not match any known + object directory, `git commit-graph ...` will exit with non-zero + status. +--[no-]progress:: + Turn progress on/off explicitly. If neither is specified, progress is + shown if standard error is connected to a terminal. COMMANDS -------- 'write':: -Write a commit-graph file based on the commits found in packfiles. +Write a commit-graph file based on the commits found in packfiles. If +the config option `core.commitGraph` is disabled, then this command will +output a warning, then return success without writing a commit-graph file. + With the `--stdin-packs` option, generate the new commit graph by walking objects only in the specified pack-indexes. (Cannot be combined @@ -42,8 +49,10 @@ with `--stdin-commits` or `--reachable`.) + With the `--stdin-commits` option, generate the new commit graph by walking commits starting at the commits specified in stdin as a list -of OIDs in hex, one OID per line. (Cannot be combined with -`--stdin-packs` or `--reachable`.) +of OIDs in hex, one OID per line. OIDs that resolve to non-commits +(either directly, or by peeling tags) are silently ignored. OIDs that +are malformed, or do not exist generate an error. (Cannot be combined +with `--stdin-packs` or `--reachable`.) + With the `--reachable` option, generate the new commit graph by walking commits starting at all refs. (Cannot be combined with `--stdin-commits` @@ -51,16 +60,56 @@ or `--stdin-packs`.) + With the `--append` option, include all commits that are present in the existing commit-graph file. - -'read':: - -Read the commit-graph file and output basic details about it. -Used for debugging purposes. ++ +With the `--changed-paths` option, compute and write information about the +paths changed between a commit and its first parent. This operation can +take a while on large repositories. It provides significant performance gains +for getting history of a directory or a file with `git log -- <path>`. If +this option is given, future commit-graph writes will automatically assume +that this option was intended. Use `--no-changed-paths` to stop storing this +data. ++ +With the `--max-new-filters=<n>` option, generate at most `n` new Bloom +filters (if `--changed-paths` is specified). If `n` is `-1`, no limit is +enforced. Only commits present in the new layer count against this +limit. To retroactively compute Bloom filters over earlier layers, it is +advised to use `--split=replace`. Overrides the `commitGraph.maxNewFilters` +configuration. ++ +With the `--split[=<strategy>]` option, write the commit-graph as a +chain of multiple commit-graph files stored in +`<dir>/info/commit-graphs`. Commit-graph layers are merged based on the +strategy and other splitting options. The new commits not already in the +commit-graph are added in a new "tip" file. This file is merged with the +existing file if the following merge conditions are met: ++ +* If `--split=no-merge` is specified, a merge is never performed, and +the remaining options are ignored. `--split=replace` overwrites the +existing chain with a new one. A bare `--split` defers to the remaining +options. (Note that merging a chain of commit graphs replaces the +existing chain with a length-1 chain where the first and only +incremental holds the entire graph). ++ +* If `--size-multiple=<X>` is not specified, let `X` equal 2. If the new +tip file would have `N` commits and the previous tip has `M` commits and +`X` times `N` is greater than `M`, instead merge the two files into a +single file. ++ +* If `--max-commits=<M>` is specified with `M` a positive integer, and the +new tip file would have more than `M` commits, then instead merge the new +tip with the previous tip. ++ +Finally, if `--expire-time=<datetime>` is not specified, let `datetime` +be the current time. After writing the split commit-graph, delete all +unused commit-graph whose modified times are older than `datetime`. 'verify':: Read the commit-graph file and verify its contents against the object database. Used to check for corrupted data. ++ +With the `--shallow` option, only check the tip commit-graph file in +a chain of split commit-graphs. EXAMPLES @@ -93,12 +142,6 @@ $ git show-ref -s | git commit-graph write --stdin-commits $ git rev-parse HEAD | git commit-graph write --stdin-commits --append ------------------------------------------------ -* Read basic information from the commit-graph file. -+ ------------------------------------------------- -$ git commit-graph read ------------------------------------------------- - GIT --- diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 4b90b9c12a..2e2c581098 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -61,14 +61,11 @@ OPTIONS -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. - ---no-gpg-sign:: - Do not GPG-sign commit, to countermand a `--gpg-sign` option - given earlier on the command line. - + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand a `--gpg-sign` option given earlier on the command line. Commit Information ------------------ @@ -79,26 +76,6 @@ A commit encapsulates: - author name, email and date - committer name and email and the commit time. -While parent object ids are provided on the command line, author and -committer information is taken from the following environment variables, -if set: - - GIT_AUTHOR_NAME - GIT_AUTHOR_EMAIL - GIT_AUTHOR_DATE - GIT_COMMITTER_NAME - GIT_COMMITTER_EMAIL - GIT_COMMITTER_DATE - -(nb "<", ">" and "\n"s are stripped) - -In case (some of) these environment variables are not set, the information -is taken from the configuration items user.name and user.email, or, if not -present, the environment variable EMAIL, or, if that is not set, -system user name and the hostname used for outgoing mail (taken -from `/etc/mailname` and falling back to the fully qualified hostname when -that file does not exist). - A commit comment is read from stdin. If a changelog entry is not provided via "<" redirection, 'git commit-tree' will just wait for one to be entered and terminated with ^D. @@ -117,6 +94,7 @@ FILES SEE ALSO -------- linkgit:git-write-tree[1] +linkgit:git-commit[1] GIT --- diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index a85c2c2a4c..95fec5f069 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -9,11 +9,13 @@ SYNOPSIS -------- [verse] 'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] - [--dry-run] [(-c | -C | --fixup | --squash) <commit>] + [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--[no-]status] - [-i | -o] [-S[<keyid>]] [--] [<file>...] + [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]] + [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]] + [--] [<pathspec>...] DESCRIPTION ----------- @@ -58,6 +60,7 @@ commit by giving the same set of parameters (options and paths). If you make a commit and then find a mistake immediately after that, you can recover from it with 'git reset'. +:git-commit: 1 OPTIONS ------- @@ -69,7 +72,7 @@ OPTIONS -p:: --patch:: - Use the interactive patch selection interface to chose + Use the interactive patch selection interface to choose which changes to commit. See linkgit:git-add[1] for details. @@ -84,11 +87,44 @@ OPTIONS Like '-C', but with `-c` the editor is invoked, so that the user can further edit the commit message. ---fixup=<commit>:: - Construct a commit message for use with `rebase --autosquash`. - The commit message will be the subject line from the specified - commit with a prefix of "fixup! ". See linkgit:git-rebase[1] - for details. +--fixup=[(amend|reword):]<commit>:: + Create a new commit which "fixes up" `<commit>` when applied with + `git rebase --autosquash`. Plain `--fixup=<commit>` creates a + "fixup!" commit which changes the content of `<commit>` but leaves + its log message untouched. `--fixup=amend:<commit>` is similar but + creates an "amend!" commit which also replaces the log message of + `<commit>` with the log message of the "amend!" commit. + `--fixup=reword:<commit>` creates an "amend!" commit which + replaces the log message of `<commit>` with its own log message + but makes no changes to the content of `<commit>`. ++ +The commit created by plain `--fixup=<commit>` has a subject +composed of "fixup!" followed by the subject line from <commit>, +and is recognized specially by `git rebase --autosquash`. The `-m` +option may be used to supplement the log message of the created +commit, but the additional commentary will be thrown away once the +"fixup!" commit is squashed into `<commit>` by +`git rebase --autosquash`. ++ +The commit created by `--fixup=amend:<commit>` is similar but its +subject is instead prefixed with "amend!". The log message of +<commit> is copied into the log message of the "amend!" commit and +opened in an editor so it can be refined. When `git rebase +--autosquash` squashes the "amend!" commit into `<commit>`, the +log message of `<commit>` is replaced by the refined log message +from the "amend!" commit. It is an error for the "amend!" commit's +log message to be empty unless `--allow-empty-message` is +specified. ++ +`--fixup=reword:<commit>` is shorthand for `--fixup=amend:<commit> +--only`. It creates an "amend!" commit with only a log message +(ignoring any changes staged in the index). When squashed by `git +rebase --autosquash`, it replaces the log message of `<commit>` +without making any other changes. ++ +Neither "fixup!" nor "amend!" commits change authorship of +`<commit>` when applied by `git rebase --autosquash`. +See linkgit:git-rebase[1] for details. --squash=<commit>:: Construct a commit message for use with `rebase --autosquash`. @@ -162,14 +198,18 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. message, the commit is aborted. This has no effect when a message is given by other means, e.g. with the `-m` or `-F` options. --s:: ---signoff:: - Add Signed-off-by line by the committer at the end of the commit - log message. The meaning of a signoff depends on the project, - but it typically certifies that committer has - the rights to submit this work under the same license and - agrees to a Developer Certificate of Origin - (see http://developercertificate.org/ for more information). +include::signoff-option.txt[] + +--trailer <token>[(=|:)<value>]:: + Specify a (<token>, <value>) pair that should be applied as a + trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ + <committer@example.com>" --trailer "Helped-by:C O Mitter \ + <committer@example.com>"` will add the "Signed-off-by" trailer + and the "Helped-by" trailer to the commit message.) + The `trailer.*` configuration variables + (linkgit:git-interpret-trailers[1]) can be used to define if + a duplicated trailer is omitted, where in the run of trailers + each trailer would appear, and other details. -n:: --no-verify:: @@ -278,22 +318,37 @@ FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].) already been staged. If used together with `--allow-empty` paths are also not required, and an empty commit will be created. +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + -u[<mode>]:: --untracked-files[=<mode>]:: Show untracked files. + +-- The mode parameter is optional (defaults to 'all'), and is used to specify the handling of untracked files; when -u is not used, the default is 'normal', i.e. show untracked files and directories. -+ + The possible options are: -+ + - 'no' - Show no untracked files - 'normal' - Shows untracked files and directories - 'all' - Also shows individual files in untracked directories. -+ + The default can be changed using the status.showUntrackedFiles configuration variable documented in linkgit:git-config[1]. +-- -v:: --verbose:: @@ -332,26 +387,23 @@ changes to tracked files. -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. - ---no-gpg-sign:: - Countermand `commit.gpgSign` configuration variable that is - set to force each and every commit to be signed. + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand both `commit.gpgSign` configuration variable, and + earlier `--gpg-sign`. \--:: Do not interpret any more arguments as options. -<file>...:: - When files are given on the command line, the command - commits the contents of the named files, without - recording the changes already staged. The contents of - these files are also staged for the next commit on top - of what have been staged before. - -:git-commit: 1 -include::date-formats.txt[] +<pathspec>...:: + When pathspec is given on the command line, commit the contents of + the files that match the pathspec without recording the changes + already added to the index. The contents of these files are also + staged for the next commit on top of what have been staged before. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. EXAMPLES -------- @@ -359,7 +411,7 @@ When recording your own work, the contents of modified files in your working tree are temporarily stored to a staging area called the "index" with 'git add'. A file can be reverted back, only in the index but not in the working tree, -to that of the last commit with `git reset HEAD -- <file>`, +to that of the last commit with `git restore --staged <file>`, which effectively reverts 'git add' and prevents the changes to this file from participating in the next commit. After building the state to be committed incrementally with these commands, @@ -446,6 +498,43 @@ alter the order the changes are committed, because the merge should be recorded as a single commit. In fact, the command refuses to run when given pathnames (but see `-i` option). +COMMIT INFORMATION +------------------ + +Author and committer information is taken from the following environment +variables, if set: + + GIT_AUTHOR_NAME + GIT_AUTHOR_EMAIL + GIT_AUTHOR_DATE + GIT_COMMITTER_NAME + GIT_COMMITTER_EMAIL + GIT_COMMITTER_DATE + +(nb "<", ">" and "\n"s are stripped) + +The author and committer names are by convention some form of a personal name +(that is, the name by which other humans refer to you), although Git does not +enforce or require any particular form. Arbitrary Unicode may be used, subject +to the constraints listed above. This name has no effect on authentication; for +that, see the `credential.username` variable in linkgit:git-config[1]. + +In case (some of) these environment variables are not set, the information +is taken from the configuration items `user.name` and `user.email`, or, if not +present, the environment variable EMAIL, or, if that is not set, +system user name and the hostname used for outgoing mail (taken +from `/etc/mailname` and falling back to the fully qualified hostname when +that file does not exist). + +The `author.name` and `committer.name` and their corresponding email options +override `user.name` and `user.email` if set and are overridden themselves by +the environment variables. + +The typical usage is to set just the `user.name` and `user.email` variables; +the other options are provided for more complex use cases. + +:git-commit: 1 +include::date-formats.txt[] DISCUSSION ---------- diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index ff9310f958..2dc4bae6da 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -9,18 +9,18 @@ git-config - Get and set repository or global options SYNOPSIS -------- [verse] -'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] name [value [value_regex]] +'git config' [<file-option>] [--type=<type>] [--fixed-value] [--show-origin] [--show-scope] [-z|--null] name [value [value-pattern]] 'git config' [<file-option>] [--type=<type>] --add name value -'git config' [<file-option>] [--type=<type>] --replace-all name value [value_regex] -'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get name [value_regex] -'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get-all name [value_regex] -'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex] +'git config' [<file-option>] [--type=<type>] [--fixed-value] --replace-all name value [value-pattern] +'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get name [value-pattern] +'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] --get-all name [value-pattern] +'git config' [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] [--fixed-value] [--name-only] --get-regexp name_regex [value-pattern] 'git config' [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch name URL -'git config' [<file-option>] --unset name [value_regex] -'git config' [<file-option>] --unset-all name [value_regex] +'git config' [<file-option>] [--fixed-value] --unset name [value-pattern] +'git config' [<file-option>] [--fixed-value] --unset-all name [value-pattern] 'git config' [<file-option>] --rename-section old_name new_name 'git config' [<file-option>] --remove-section name -'git config' [<file-option>] [--show-origin] [-z|--null] [--name-only] -l | --list +'git config' [<file-option>] [--show-origin] [--show-scope] [-z|--null] [--name-only] -l | --list 'git config' [<file-option>] --get-color name [default] 'git config' [<file-option>] --get-colorbool name [stdout-is-tty] 'git config' [<file-option>] -e | --edit @@ -33,10 +33,13 @@ escaped. Multiple lines can be added to an option by using the `--add` option. If you want to update or unset an option which can occur on multiple -lines, a POSIX regexp `value_regex` needs to be given. Only the -existing values that match the regexp are updated or unset. If -you want to handle the lines that do *not* match the regex, just -prepend a single exclamation mark in front (see also <<EXAMPLES>>). +lines, a `value-pattern` (which is an extended regular expression, +unless the `--fixed-value` option is given) needs to be given. Only the +existing values that match the pattern are updated or unset. If +you want to handle the lines that do *not* match the pattern, just +prepend a single exclamation mark in front (see also <<EXAMPLES>>), +but note that this only works when the `--fixed-value` option is not +in use. The `--type=<type>` option instructs 'git config' to ensure that incoming and outgoing values are canonicalize-able under the given <type>. If no @@ -68,16 +71,17 @@ codes are: On success, the command returns the exit code 0. +[[OPTIONS]] OPTIONS ------- --replace-all:: Default behavior is to replace at most one line. This replaces - all lines matching the key (and optionally the value_regex). + all lines matching the key (and optionally the `value-pattern`). --add:: Adds a new line to the option without altering any existing - values. This is the same as providing '^$' as the value_regex + values. This is the same as providing '^$' as the `value-pattern` in `--replace-all`. --get:: @@ -140,7 +144,13 @@ See also <<FILES>>. -f config-file:: --file config-file:: - Use the given config file instead of the one specified by GIT_CONFIG. + For writing options: write to the specified file rather than the + repository `.git/config`. ++ +For reading options: read only from the specified file rather than from all +available files. ++ +See also <<FILES>>. --blob blob:: Similar to `--file` but use the given blob instead of a file. E.g. @@ -165,6 +175,12 @@ See also <<FILES>>. --list:: List all variables set in config file, along with their values. +--fixed-value:: + When used with the `value-pattern` argument, treat `value-pattern` as + an exact string instead of a regular expression. This will restrict + the name/value pairs that are matched to only those where the value + is exactly equal to the `value-pattern`. + --type <type>:: 'git config' will ensure that any input or output is valid under the given type constraint(s), and will canonicalize outgoing values in `<type>`'s @@ -222,6 +238,11 @@ Valid `<type>`'s include: the actual origin (config file path, ref, or blob id if applicable). +--show-scope:: + Similar to `--show-origin` in that it augments the output of + all queried config options with the scope of that value + (local, global, system, command). + --get-colorbool name [stdout-is-tty]:: Find the color setting for `name` (e.g. `color.diff`) and output @@ -311,20 +332,18 @@ All writing options will per default write to the repository specific configuration file. Note that this also affects options like `--replace-all` and `--unset`. *'git config' will only ever change one file at a time*. -You can override these rules either by command-line options or by environment -variables. The `--global`, `--system` and `--worktree` options will limit -the file used to the global, system-wide or per-worktree file respectively. -The `GIT_CONFIG` environment variable has a similar effect, but you -can specify any filename you want. +You can override these rules using the `--global`, `--system`, +`--local`, `--worktree`, and `--file` command-line options; see +<<OPTIONS>> above. ENVIRONMENT ----------- -GIT_CONFIG:: - Take the configuration from the given file instead of .git/config. - Using the "--global" option forces this to ~/.gitconfig. Using the - "--system" option forces this to $(prefix)/etc/gitconfig. +GIT_CONFIG_GLOBAL:: +GIT_CONFIG_SYSTEM:: + Take the configuration from the given files instead from global or + system-level configuration. See linkgit:git[1] for details. GIT_CONFIG_NOSYSTEM:: Whether to skip reading settings from the system-wide @@ -332,6 +351,28 @@ GIT_CONFIG_NOSYSTEM:: See also <<FILES>>. +GIT_CONFIG_COUNT:: +GIT_CONFIG_KEY_<n>:: +GIT_CONFIG_VALUE_<n>:: + If GIT_CONFIG_COUNT is set to a positive number, all environment pairs + GIT_CONFIG_KEY_<n> and GIT_CONFIG_VALUE_<n> up to that number will be + added to the process's runtime configuration. The config pairs are + zero-indexed. Any missing key or value is treated as an error. An empty + GIT_CONFIG_COUNT is treated the same as GIT_CONFIG_COUNT=0, namely no + pairs are processed. These environment variables will override values + in configuration files, but will be overridden by any explicit options + passed via `git -c`. ++ +This is useful for cases where you want to spawn multiple git commands +with a common configuration but cannot depend on a configuration file, +for example when writing scripts. + +GIT_CONFIG:: + If no `--file` option is provided to `git config`, use the file + given by `GIT_CONFIG` as if it were provided via `--file`. This + variable has no effect on other Git commands, and is mostly for + historical compatibility; there is generally no reason to use it + instead of the `--file` option. [[EXAMPLES]] EXAMPLES @@ -339,33 +380,35 @@ EXAMPLES Given a .git/config like this: - # - # This is the config file, and - # a '#' or ';' character indicates - # a comment - # - - ; core variables - [core] - ; Don't trust file modes - filemode = false - - ; Our diff algorithm - [diff] - external = /usr/local/bin/diff-wrapper - renames = true - - ; Proxy settings - [core] - gitproxy=proxy-command for kernel.org - gitproxy=default-proxy ; for all the rest - - ; HTTP - [http] - sslVerify - [http "https://weak.example.com"] - sslVerify = false - cookieFile = /tmp/cookie.txt +------------ +# +# This is the config file, and +# a '#' or ';' character indicates +# a comment +# + +; core variables +[core] + ; Don't trust file modes + filemode = false + +; Our diff algorithm +[diff] + external = /usr/local/bin/diff-wrapper + renames = true + +; Proxy settings +[core] + gitproxy=proxy-command for kernel.org + gitproxy=default-proxy ; for all the rest + +; HTTP +[http] + sslVerify +[http "https://weak.example.com"] + sslVerify = false + cookieFile = /tmp/cookie.txt +------------ you can set the filemode to true with diff --git a/Documentation/git-credential-store.txt b/Documentation/git-credential-store.txt index 693dd9d9d7..76b0798856 100644 --- a/Documentation/git-credential-store.txt +++ b/Documentation/git-credential-store.txt @@ -94,6 +94,10 @@ stored on its own line as a URL like: https://user:pass@example.com ------------------------------ +No other kinds of lines (e.g. empty lines or comment lines) are +allowed in the file, even though some may be silently ignored. Do +not view or edit the file with editors. + When Git needs authentication for a particular URL context, credential-store will consider that context a pattern to match against each entry in the credentials file. If the protocol, hostname, and diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt index b211440373..206e3c5f40 100644 --- a/Documentation/git-credential.txt +++ b/Documentation/git-credential.txt @@ -19,8 +19,7 @@ from system-specific helpers, as well as prompting the user for usernames and passwords. The git-credential command exposes this interface to scripts which may want to retrieve, store, or prompt for credentials in the same manner as Git. The design of this scriptable -interface models the internal C API; see -link:technical/api-credentials.html[the Git credential API] for more +interface models the internal C API; see credential.h for more background on the concepts. git-credential takes an "action" option on the command-line (one of @@ -104,17 +103,20 @@ INPUT/OUTPUT FORMAT `git credential` reads and/or writes (depending on the action used) credential information in its standard input/output. This information can correspond either to keys for which `git credential` will obtain -the login/password information (e.g. host, protocol, path), or to the -actual credential data to be obtained (login/password). +the login information (e.g. host, protocol, path), or to the actual +credential data to be obtained (username/password). The credential is split into a set of named attributes, with one -attribute per line. Each attribute is -specified by a key-value pair, separated by an `=` (equals) sign, -followed by a newline. The key may contain any bytes except `=`, -newline, or NUL. The value may contain any bytes except newline or NUL. +attribute per line. Each attribute is specified by a key-value pair, +separated by an `=` (equals) sign, followed by a newline. + +The key may contain any bytes except `=`, newline, or NUL. The value may +contain any bytes except newline or NUL. + In both cases, all bytes are treated as-is (i.e., there is no quoting, and one cannot transmit a value with newline or NUL in it). The list of attributes is terminated by a blank line or end-of-file. + Git understands the following attributes: `protocol`:: @@ -124,7 +126,8 @@ Git understands the following attributes: `host`:: - The remote hostname for a network credential. + The remote hostname for a network credential. This includes + the port number if one was specified (e.g., "example.com:8088"). `path`:: @@ -135,7 +138,7 @@ Git understands the following attributes: `username`:: The credential's username, if we already have one (e.g., from a - URL, from the user, or from a previously run helper). + URL, the configuration, the user, or from a previously run helper). `password`:: @@ -147,8 +150,16 @@ Git understands the following attributes: value is parsed as a URL and treated as if its constituent parts were read (e.g., `url=https://example.com` would behave as if `protocol=https` and `host=example.com` had been provided). This - can help callers avoid parsing URLs themselves. Note that any - components which are missing from the URL (e.g., there is no - username in the example above) will be set to empty; if you want - to provide a URL and override some attributes, provide the URL - attribute first, followed by any overrides. + can help callers avoid parsing URLs themselves. ++ +Note that specifying a protocol is mandatory and if the URL +doesn't specify a hostname (e.g., "cert:///path/to/file") the +credential will contain a hostname attribute whose value is an +empty string. ++ +Components which are missing from the URL (e.g., there is no +username in the example above) will be left unset. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.txt index f98b7c6ed7..f2e4a47ebe 100644 --- a/Documentation/git-cvsserver.txt +++ b/Documentation/git-cvsserver.txt @@ -24,6 +24,18 @@ Usage: [verse] 'git-cvsserver' [<options>] [pserver|server] [<directory> ...] +DESCRIPTION +----------- + +This application is a CVS emulation layer for Git. + +It is highly functional. However, not all methods are implemented, +and for those methods that are implemented, +not all switches are implemented. + +Testing has been done using both the CLI CVS client, and the Eclipse CVS +plugin. Most functionality works fine with both of these clients. + OPTIONS ------- @@ -57,18 +69,6 @@ access still needs to be enabled by the `gitcvs.enabled` config option unless `--export-all` was given, too. -DESCRIPTION ------------ - -This application is a CVS emulation layer for Git. - -It is highly functional. However, not all methods are implemented, -and for those methods that are implemented, -not all switches are implemented. - -Testing has been done using both the CLI CVS client, and the Eclipse CVS -plugin. Most functionality works fine with both of these clients. - LIMITATIONS ----------- @@ -232,7 +232,7 @@ write so it might not be enough to grant the users using 'git-cvsserver' write access to the database file without granting them write access to the directory, too. -The database can not be reliably regenerated in a +The database cannot be reliably regenerated in a consistent form after the branch it is tracking has changed. Example: For merged branches, 'git-cvsserver' only tracks one branch of development, and after a 'git merge' an @@ -294,7 +294,7 @@ In `dbDriver` and `dbUser` you can use the following variables: Git directory name %g:: Git directory name, where all characters except for - alpha-numeric ones, `.`, and `-` are replaced with + alphanumeric ones, `.`, and `-` are replaced with `_` (this should make it easier to use the directory name in a filename if wanted) %m:: diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt index a88f6ae2c6..c6a79c2a0f 100644 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@ -63,9 +63,10 @@ OPTIONS Automatically implies --tags. --abbrev=<n>:: - Instead of using the default 7 hexadecimal digits as the - abbreviated object name, use <n> digits, or as many digits - as needed to form a unique object name. An <n> of 0 + Instead of using the default number of hexadecimal digits (which + will vary according to the number of objects in the repository with + a default of 7) of the abbreviated object name, use <n> digits, or + as many digits as needed to form a unique object name. An <n> of 0 will suppress long format, only showing the closest tag. --candidates=<n>:: @@ -139,8 +140,11 @@ at the end. The number of additional commits is the number of commits which would be displayed by "git log v1.0.4..parent". -The hash suffix is "-g" + unambiguous abbreviation for the tip commit -of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`). +The hash suffix is "-g" + an unambigous abbreviation for the tip commit +of parent (which was `2414721b194453f058079d897d13c4e377f92dc6`). The +length of the abbreviation scales as the repository grows, using the +approximate number of objects in the repository and a bit of math +around the birthday paradox, and defaults to a minimum of 7. The "g" prefix stands for "git" and is used to allow describing the version of a software depending on the SCM the software is managed with. This is useful in an environment where people may use different SCMs. diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.txt index f4bd8155c0..27acb31cbf 100644 --- a/Documentation/git-diff-index.txt +++ b/Documentation/git-diff-index.txt @@ -9,7 +9,7 @@ git-diff-index - Compare a tree to the working tree or index SYNOPSIS -------- [verse] -'git diff-index' [-m] [--cached] [<common diff options>] <tree-ish> [<path>...] +'git diff-index' [-m] [--cached] [--merge-base] [<common diff options>] <tree-ish> [<path>...] DESCRIPTION ----------- @@ -27,7 +27,12 @@ include::diff-options.txt[] The id of a tree object to diff against. --cached:: - do not consider the on-disk file at all + Do not consider the on-disk file at all. + +--merge-base:: + Instead of comparing <tree-ish> directly, use the merge base + between <tree-ish> and HEAD instead. <tree-ish> must be a + commit. -m:: By default, files recorded in the index but not checked diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 5c8a2a5e97..2fc24c542f 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git diff-tree' [--stdin] [-m] [-s] [-v] [--no-commit-id] [--pretty] - [-t] [-r] [-c | --cc] [--combined-all-paths] [--root] + [-t] [-r] [-c | --cc] [--combined-all-paths] [--root] [--merge-base] [<common diff options>] <tree-ish> [<tree-ish>] [<path>...] DESCRIPTION @@ -43,6 +43,11 @@ include::diff-options.txt[] When `--root` is specified the initial commit will be shown as a big creation event. This is equivalent to a diff against the NULL tree. +--merge-base:: + Instead of comparing the <tree-ish>s directly, use the merge + base between the two <tree-ish>s as the "before" side. There + must be two <tree-ish>s given and they must both be commits. + --stdin:: When `--stdin` is specified, the command does not take <tree-ish> arguments from the command line. Instead, it diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index 72179d993c..6236c75c9b 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -10,16 +10,18 @@ SYNOPSIS -------- [verse] 'git diff' [<options>] [<commit>] [--] [<path>...] -'git diff' [<options>] --cached [<commit>] [--] [<path>...] -'git diff' [<options>] <commit> <commit> [--] [<path>...] +'git diff' [<options>] --cached [--merge-base] [<commit>] [--] [<path>...] +'git diff' [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...] +'git diff' [<options>] <commit>...<commit> [--] [<path>...] 'git diff' [<options>] <blob> <blob> 'git diff' [<options>] --no-index [--] <path> <path> DESCRIPTION ----------- Show changes between the working tree and the index or a tree, changes -between the index and a tree, changes between two trees, changes between -two blob objects, or changes between two files on disk. +between the index and a tree, changes between two trees, changes resulting +from a merge, changes between two blob objects, or changes between two +files on disk. 'git diff' [<options>] [--] [<path>...]:: @@ -36,9 +38,9 @@ two blob objects, or changes between two files on disk. running the command in a working tree controlled by Git and at least one of the paths points outside the working tree, or when running the command outside a working tree - controlled by Git. + controlled by Git. This form implies `--exit-code`. -'git diff' [<options>] --cached [<commit>] [--] [<path>...]:: +'git diff' [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]:: This form is to view the changes you staged for the next commit relative to the named <commit>. Typically you @@ -47,23 +49,45 @@ two blob objects, or changes between two files on disk. If HEAD does not exist (e.g. unborn branches) and <commit> is not given, it shows all staged changes. --staged is a synonym of --cached. ++ +If --merge-base is given, instead of using <commit>, use the merge base +of <commit> and HEAD. `git diff --cached --merge-base A` is equivalent to +`git diff --cached $(git merge-base A HEAD)`. -'git diff' [<options>] <commit> [--] [<path>...]:: +'git diff' [<options>] [--merge-base] <commit> [--] [<path>...]:: This form is to view the changes you have in your working tree relative to the named <commit>. You can use HEAD to compare it with the latest commit, or a branch name to compare with the tip of a different branch. ++ +If --merge-base is given, instead of using <commit>, use the merge base +of <commit> and HEAD. `git diff --merge-base A` is equivalent to +`git diff $(git merge-base A HEAD)`. -'git diff' [<options>] <commit> <commit> [--] [<path>...]:: +'git diff' [<options>] [--merge-base] <commit> <commit> [--] [<path>...]:: This is to view the changes between two arbitrary <commit>. ++ +If --merge-base is given, use the merge base of the two commits for the +"before" side. `git diff --merge-base A B` is equivalent to +`git diff $(git merge-base A B) B`. + +'git diff' [<options>] <commit> <commit>... <commit> [--] [<path>...]:: + + This form is to view the results of a merge commit. The first + listed <commit> must be the merge itself; the remaining two or + more commits should be its parents. A convenient way to produce + the desired set of revisions is to use the `^@` suffix. + For instance, if `master` names a merge commit, `git diff master + master^@` gives the same combined diff as `git show master`. 'git diff' [<options>] <commit>..<commit> [--] [<path>...]:: - This is synonymous to the previous form. If <commit> on + This is synonymous to the earlier form (without the `..`) for + viewing the changes between two arbitrary <commit>. If <commit> on one side is omitted, it will have the same effect as using HEAD instead. @@ -71,20 +95,20 @@ two blob objects, or changes between two files on disk. This form is to view the changes on the branch containing and up to the second <commit>, starting at a common ancestor - of both <commit>. "git diff A\...B" is equivalent to - "git diff $(git merge-base A B) B". You can omit any one + of both <commit>. `git diff A...B` is equivalent to + `git diff $(git merge-base A B) B`. You can omit any one of <commit>, which has the same effect as using HEAD instead. Just in case you are doing something exotic, it should be noted that all of the <commit> in the above description, except -in the last two forms that use ".." notations, can be any -<tree>. +in the `--merge-base` case and in the last two forms that use `..` +notations, can be any <tree>. For a more complete list of ways to spell <commit>, see "SPECIFYING REVISIONS" section in linkgit:gitrevisions[7]. However, "diff" is about comparing two _endpoints_, not ranges, -and the range notations ("<commit>..<commit>" and -"<commit>\...<commit>") do not mean a range as defined in the +and the range notations (`<commit>..<commit>` and +`<commit>...<commit>`) do not mean a range as defined in the "SPECIFYING RANGES" section in linkgit:gitrevisions[7]. 'git diff' [<options>] <blob> <blob>:: @@ -132,9 +156,9 @@ $ git diff HEAD <3> + <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:: + @@ -196,7 +220,8 @@ linkgit:git-difftool[1], linkgit:git-log[1], linkgit:gitdiffcore[7], linkgit:git-format-patch[1], -linkgit:git-apply[1] +linkgit:git-apply[1], +linkgit:git-show[1] GIT --- diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index 484c485fd0..143b0c49d7 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -34,6 +34,14 @@ OPTIONS This is the default behaviour; the option is provided to override any configuration settings. +--rotate-to=<file>:: + Start showing the diff for the given path, + the paths before it will move to end and output. + +--skip-to=<file>:: + Start showing the diff for the given path, skipping all + the paths before it. + -t <tool>:: --tool=<tool>:: Use the diff tool specified by <tool>. Valid values include diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 64c01ba918..1978dbdc6a 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -17,9 +17,9 @@ This program dumps the given revisions in a form suitable to be piped into 'git fast-import'. You can use it as a human-readable bundle replacement (see -linkgit:git-bundle[1]), or as a kind of an interactive -'git filter-branch'. - +linkgit:git-bundle[1]), or as a format that can be edited before being +fed to 'git fast-import' in order to do history rewrites (an ability +relied on by tools like 'git filter-repo'). OPTIONS ------- @@ -75,11 +75,20 @@ produced incorrect results if you gave these options. Before processing any input, load the marks specified in <file>. The input file must exist, must be readable, and must use the same format as produced by --export-marks. + +--mark-tags:: + In addition to labelling blobs and commits with mark ids, also + label tags. This is useful in conjunction with + `--export-marks` and `--import-marks`, and is also useful (and + necessary) for exporting of nested tags. It does not hurt + other cases and would be the default, but many fast-import + frontends are not prepared to accept tags with mark + identifiers. + -Any commits that have already been marked will not be exported again. -If the backend uses a similar --import-marks file, this allows for -incremental bidirectional exporting of the repository by keeping the -marks the same across runs. +Any commits (or tags) that have already been marked will not be +exported again. If the backend uses a similar --import-marks file, +this allows for incremental bidirectional exporting of the repository +by keeping the marks the same across runs. --fake-missing-tagger:: Some old repositories have tags without a tagger. The @@ -110,13 +119,18 @@ marks the same across runs. the shape of the history and stored tree. See the section on `ANONYMIZING` below. +--anonymize-map=<from>[:<to>]:: + Convert token `<from>` to `<to>` in the anonymized output. If + `<to>` is omitted, map `<from>` to itself (i.e., do not + anonymize it). 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 + --reference-excluded-parents to instead have 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 @@ -129,6 +143,13 @@ marks the same across runs. for intermediary filters (e.g. for rewriting commit messages which refer to older commits, or for stripping blobs by id). +--reencode=(yes|no|abort):: + Specify how to handle `encoding` header in commit objects. When + asking to 'abort' (which is the default), this program will die + when encountering such a commit object. With 'yes', the commit + message will be re-encoded into UTF-8. With 'no', the original + encoding will be preserved. + --refspec:: Apply the specified refspec to each ref exported. Multiple of them can be specified. @@ -222,6 +243,30 @@ collapse "User 0", "User 1", etc into "User X"). This produces a much smaller output, and it is usually easy to quickly confirm that there is no private data in the stream. +Reproducing some bugs may require referencing particular commits or +paths, which becomes challenging after refnames and paths have been +anonymized. You can ask for a particular token to be left as-is or +mapped to a new value. For example, if you have a bug which reproduces +with `git rev-list sensitive -- secret.c`, you can run: + +--------------------------------------------------- +$ git fast-export --anonymize --all \ + --anonymize-map=sensitive:foo \ + --anonymize-map=secret.c:bar.c \ + >stream +--------------------------------------------------- + +After importing the stream, you can then run `git rev-list foo -- bar.c` +in the anonymized repository. + +Note that paths and refnames are split into tokens at slash boundaries. +The command above would anonymize `subdir/secret.c` as something like +`path123/bar.c`; you could then search for `bar.c` in the anonymized +repository to determine the final pathname. + +To make referencing the final pathname simpler, you can map each path +component; so if you also anonymize `subdir` to `publicdir`, then the +final pathname would be `publicdir/bar.c`. LIMITATIONS ----------- diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt index 6ab4441caf..39cfa05b28 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.txt @@ -122,6 +122,26 @@ Locations of Marks Files Relative and non-relative marks may be combined by interweaving --(no-)-relative-marks with the --(import|export)-marks= options. +Submodule Rewriting +~~~~~~~~~~~~~~~~~~~ + +--rewrite-submodules-from=<name>:<file>:: +--rewrite-submodules-to=<name>:<file>:: + Rewrite the object IDs for the submodule specified by <name> from the values + used in the from <file> to those used in the to <file>. The from marks should + have been created by `git fast-export`, and the to marks should have been + created by `git fast-import` when importing that same submodule. ++ +<name> may be any arbitrary string not containing a colon character, but the +same value must be used with both options when specifying corresponding marks. +Multiple submodules may be specified with different values for <name>. It is an +error not to use these options in corresponding pairs. ++ +These options are primarily useful when converting a repository from one hash +algorithm to another; without them, fast-import will fail if it encounters a +submodule because it has no way of writing the object ID into the new hash +algorithm. + Performance and Compression Tuning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -273,7 +293,14 @@ by users who are located in the same location and time zone. In this case a reasonable offset from UTC could be assumed. + Unlike the `rfc2822` format, this format is very strict. Any -variation in formatting will cause fast-import to reject the value. +variation in formatting will cause fast-import to reject the value, +and some sanity checks on the numeric values may also be performed. + +`raw-permissive`:: + This is the same as `raw` except that no sanity checks on + the numeric epoch and local offset are performed. This can + be useful when trying to filter or import an existing history + with e.g. bogus timezone values. `rfc2822`:: This is the standard email format as described by RFC 2822. @@ -352,6 +379,13 @@ and control the current import process. More detailed discussion `commit` command. This command is optional and is not needed to perform an import. +`alias`:: + Record that a mark refers to a given object without first + creating any new object. Using --import-marks and referring + to missing marks will cause fast-import to fail, so aliases + can provide a way to set otherwise pruned commits to a valid + value (e.g. the nearest non-pruned ancestor). + `checkpoint`:: Forces fast-import to close the current packfile, generate its unique SHA-1 checksum and index, and start a new packfile. @@ -403,9 +437,10 @@ change to the project. original-oid? ('author' (SP <name>)? SP LT <email> GT SP <when> LF)? 'committer' (SP <name>)? SP LT <email> GT SP <when> LF + ('encoding' SP <encoding>)? data ('from' SP <commit-ish> LF)? - ('merge' SP <commit-ish> LF)? + ('merge' SP <commit-ish> LF)* (filemodify | filedelete | filecopy | filerename | filedeleteall | notemodify)* LF? .... @@ -439,7 +474,7 @@ the same commit, as `filedeleteall` wipes the branch clean (see below). The `LF` after the command is optional (it used to be required). Note that for reasons of backward compatibility, if the commit ends with a -`data` command (i.e. it has has no `from`, `merge`, `filemodify`, +`data` command (i.e. it has no `from`, `merge`, `filemodify`, `filedelete`, `filecopy`, `filerename`, `filedeleteall` or `notemodify` commands) then two `LF` commands may appear at the end of the command instead of just one. @@ -470,6 +505,12 @@ that was selected by the --date-format=<fmt> command-line option. See ``Date Formats'' above for the set of supported formats, and their syntax. +`encoding` +^^^^^^^^^^ +The optional `encoding` command indicates the encoding of the commit +message. Most commits are UTF-8 and the encoding is omitted, but this +allows importing commit messages into git without first reencoding them. + `from` ^^^^^^ The `from` command is used to specify the commit to initialize @@ -773,7 +814,7 @@ may have uses for this information 'original-oid' SP <object-identifier> LF .... -where `<object-identifer>` is any string not containing LF. +where `<object-identifier>` is any string not containing LF. `tag` ~~~~~ @@ -782,6 +823,7 @@ lightweight (non-annotated) tags see the `reset` command below. .... 'tag' SP <name> LF + mark? 'from' SP <commit-ish> LF original-oid? 'tagger' (SP <name>)? SP LT <email> GT SP <when> LF @@ -921,6 +963,21 @@ a data chunk which does not have an LF as its last byte. + The `LF` after `<delim> LF` is optional (it used to be required). +`alias` +~~~~~~~ +Record that a mark refers to a given object without first creating any +new object. + +.... + 'alias' LF + mark + 'to' SP <commit-ish> LF + LF? +.... + +For a detailed description of `<commit-ish>` see above under `from`. + + `checkpoint` ~~~~~~~~~~~~ Forces fast-import to close the current packfile, start a new one, and to diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.txt index 266d63cf11..550c16ca61 100644 --- a/Documentation/git-fetch.txt +++ b/Documentation/git-fetch.txt @@ -48,6 +48,10 @@ include::fetch-options.txt[] include::pull-fetch-param.txt[] +--stdin:: + Read refspecs, one per line, from stdin in addition to those provided + as arguments. The "tag <name>" format is not supported. + include::urls-remotes.txt[] @@ -129,7 +133,7 @@ remember to run that, set `fetch.prune` globally, or linkgit:git-config[1]. Here's where things get tricky and more specific. The pruning feature -doesn't actually care about branches, instead it'll prune local <-> +doesn't actually care about branches, instead it'll prune local <--> remote-references as a function of the refspec of the remote (see `<refspec>` and <<CRTB,CONFIGURED REMOTE-TRACKING BRANCHES>> above). @@ -255,14 +259,14 @@ refspec. * Using refspecs explicitly: + ------------------------------------------------ -$ git fetch origin +pu:pu maint:tmp +$ git fetch origin +seen:seen maint:tmp ------------------------------------------------ + -This updates (or creates, as necessary) branches `pu` and `tmp` in +This updates (or creates, as necessary) branches `seen` and `tmp` in the local repository by fetching from the branches (respectively) -`pu` and `maint` from the remote repository. +`seen` and `maint` from the remote repository. + -The `pu` branch will be updated even if it is does not fast-forward, +The `seen` branch will be updated even if it does not fast-forward, 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 @@ -285,7 +289,7 @@ BUGS ---- Using --recurse-submodules can only fetch new commits in already checked out submodules right now. When e.g. upstream added a new submodule in the -just fetched commits of the superproject the submodule itself can not be +just fetched commits of the superproject the submodule itself cannot be fetched, making it impossible to check out that submodule later without having to do a fetch again. This is expected to be fixed in a future Git version. diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 6b53dd7e06..62e482a95e 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -16,6 +16,19 @@ SYNOPSIS [--original <namespace>] [-d <directory>] [-f | --force] [--state-branch <branch>] [--] [<rev-list options>...] +WARNING +------- +'git filter-branch' has a plethora of pitfalls that can produce non-obvious +manglings of the intended history rewrite (and can leave you with little +time to investigate such problems since it has such abysmal performance). +These safety and performance issues cannot be backward compatibly fixed and +as such, its use is not recommended. Please use an alternative history +filtering tool such as https://github.com/newren/git-filter-repo/[git +filter-repo]. If you still need to use 'git filter-branch', please +carefully read <<SAFETY>> (and <<PERFORMANCE>>) to learn about the land +mines of filter-branch, and then vigilantly avoid as many of the hazards +listed there as reasonably possible. + DESCRIPTION ----------- Lets you rewrite Git revision history by rewriting the branches mentioned @@ -445,36 +458,245 @@ warned. (or if your git-gc is not new enough to support arguments to `--prune`, use `git repack -ad; git prune` instead). -NOTES ------ - -git-filter-branch allows you to make complex shell-scripted rewrites -of your Git history, but you probably don't need this flexibility if -you're simply _removing unwanted data_ like large files or passwords. -For those operations you may want to consider -http://rtyley.github.io/bfg-repo-cleaner/[The BFG Repo-Cleaner], -a JVM-based alternative to git-filter-branch, typically at least -10-50x faster for those use-cases, and with quite different -characteristics: - -* Any particular version of a file is cleaned exactly _once_. The BFG, - unlike git-filter-branch, does not give you the opportunity to - handle a file differently based on where or when it was committed - within your history. This constraint gives the core performance - benefit of The BFG, and is well-suited to the task of cleansing bad - data - you don't care _where_ the bad data is, you just want it - _gone_. - -* By default The BFG takes full advantage of multi-core machines, - cleansing commit file-trees in parallel. git-filter-branch cleans - commits sequentially (i.e. in a single-threaded manner), though it - _is_ possible to write filters that include their own parallelism, - in the scripts executed against each commit. - -* The http://rtyley.github.io/bfg-repo-cleaner/#examples[command options] - are much more restrictive than git-filter branch, and dedicated just - to the tasks of removing unwanted data- e.g: - `--strip-blobs-bigger-than 1M`. +[[PERFORMANCE]] +PERFORMANCE +----------- + +The performance of git-filter-branch is glacially slow; its design makes it +impossible for a backward-compatible implementation to ever be fast: + +* In editing files, git-filter-branch by design checks out each and + every commit as it existed in the original repo. If your repo has + `10^5` files and `10^5` commits, but each commit only modifies five + files, then git-filter-branch will make you do `10^10` modifications, + despite only having (at most) `5*10^5` unique blobs. + +* If you try and cheat and try to make git-filter-branch only work on + files modified in a commit, then two things happen + + ** you run into problems with deletions whenever the user is simply + trying to rename files (because attempting to delete files that + don't exist looks like a no-op; it takes some chicanery to remap + deletes across file renames when the renames happen via arbitrary + user-provided shell) + + ** even if you succeed at the map-deletes-for-renames chicanery, you + still technically violate backward compatibility because users + are allowed to filter files in ways that depend upon topology of + commits instead of filtering solely based on file contents or + names (though this has not been observed in the wild). + +* Even if you don't need to edit files but only want to e.g. rename or + remove some and thus can avoid checking out each file (i.e. you can + use --index-filter), you still are passing shell snippets for your + filters. This means that for every commit, you have to have a + prepared git repo where those filters can be run. That's a + significant setup. + +* Further, several additional files are created or updated per commit + by git-filter-branch. Some of these are for supporting the + convenience functions provided by git-filter-branch (such as map()), + while others are for keeping track of internal state (but could have + also been accessed by user filters; one of git-filter-branch's + regression tests does so). This essentially amounts to using the + filesystem as an IPC mechanism between git-filter-branch and the + user-provided filters. Disks tend to be a slow IPC mechanism, and + writing these files also effectively represents a forced + synchronization point between separate processes that we hit with + every commit. + +* The user-provided shell commands will likely involve a pipeline of + commands, resulting in the creation of many processes per commit. + Creating and running another process takes a widely varying amount + of time between operating systems, but on any platform it is very + slow relative to invoking a function. + +* git-filter-branch itself is written in shell, which is kind of slow. + This is the one performance issue that could be backward-compatibly + fixed, but compared to the above problems that are intrinsic to the + design of git-filter-branch, the language of the tool itself is a + relatively minor issue. + + ** Side note: Unfortunately, people tend to fixate on the + written-in-shell aspect and periodically ask if git-filter-branch + could be rewritten in another language to fix the performance + issues. Not only does that ignore the bigger intrinsic problems + with the design, it'd help less than you'd expect: if + git-filter-branch itself were not shell, then the convenience + functions (map(), skip_commit(), etc) and the `--setup` argument + could no longer be executed once at the beginning of the program + but would instead need to be prepended to every user filter (and + thus re-executed with every commit). + +The https://github.com/newren/git-filter-repo/[git filter-repo] tool is +an alternative to git-filter-branch which does not suffer from these +performance problems or the safety problems (mentioned below). For those +with existing tooling which relies upon git-filter-branch, 'git +filter-repo' also provides +https://github.com/newren/git-filter-repo/blob/master/contrib/filter-repo-demos/filter-lamely[filter-lamely], +a drop-in git-filter-branch replacement (with a few caveats). While +filter-lamely suffers from all the same safety issues as +git-filter-branch, it at least ameliorates the performance issues a +little. + +[[SAFETY]] +SAFETY +------ + +git-filter-branch is riddled with gotchas resulting in various ways to +easily corrupt repos or end up with a mess worse than what you started +with: + +* Someone can have a set of "working and tested filters" which they + document or provide to a coworker, who then runs them on a different + OS where the same commands are not working/tested (some examples in + the git-filter-branch manpage are also affected by this). + BSD vs. GNU userland differences can really bite. If lucky, error + messages are spewed. But just as likely, the commands either don't + do the filtering requested, or silently corrupt by making some + unwanted change. The unwanted change may only affect a few commits, + so it's not necessarily obvious either. (The fact that problems + won't necessarily be obvious means they are likely to go unnoticed + until the rewritten history is in use for quite a while, at which + point it's really hard to justify another flag-day for another + rewrite.) + +* Filenames with spaces are often mishandled by shell snippets since + they cause problems for shell pipelines. Not everyone is familiar + with find -print0, xargs -0, git-ls-files -z, etc. Even people who + are familiar with these may assume such flags are not relevant + because someone else renamed any such files in their repo back + before the person doing the filtering joined the project. And + often, even those familiar with handling arguments with spaces may + not do so just because they aren't in the mindset of thinking about + everything that could possibly go wrong. + +* Non-ascii filenames can be silently removed despite being in a + desired directory. Keeping only wanted paths is often done using + pipelines like `git ls-files | grep -v ^WANTED_DIR/ | xargs git rm`. + ls-files will only quote filenames if needed, so folks may not + notice that one of the files didn't match the regex (at least not + until it's much too late). Yes, someone who knows about + core.quotePath can avoid this (unless they have other special + characters like \t, \n, or "), and people who use ls-files -z with + something other than grep can avoid this, but that doesn't mean they + will. + +* Similarly, when moving files around, one can find that filenames + with non-ascii or special characters end up in a different + directory, one that includes a double quote character. (This is + technically the same issue as above with quoting, but perhaps an + interesting different way that it can and has manifested as a + problem.) + +* It's far too easy to accidentally mix up old and new history. It's + still possible with any tool, but git-filter-branch almost + invites it. If lucky, the only downside is users getting frustrated + that they don't know how to shrink their repo and remove the old + stuff. If unlucky, they merge old and new history and end up with + multiple "copies" of each commit, some of which have unwanted or + sensitive files and others which don't. This comes about in + multiple different ways: + + ** the default to only doing a partial history rewrite ('--all' is not + the default and few examples show it) + + ** the fact that there's no automatic post-run cleanup + + ** the fact that --tag-name-filter (when used to rename tags) doesn't + remove the old tags but just adds new ones with the new name + + ** the fact that little educational information is provided to inform + users of the ramifications of a rewrite and how to avoid mixing old + and new history. For example, this man page discusses how users + need to understand that they need to rebase their changes for all + their branches on top of new history (or delete and reclone), but + that's only one of multiple concerns to consider. See the + "DISCUSSION" section of the git filter-repo manual page for more + details. + +* Annotated tags can be accidentally converted to lightweight tags, + due to either of two issues: + + ** Someone can do a history rewrite, realize they messed up, restore + from the backups in refs/original/, and then redo their + git-filter-branch command. (The backup in refs/original/ is not a + real backup; it dereferences tags first.) + + ** Running git-filter-branch with either --tags or --all in your + <rev-list options>. In order to retain annotated tags as + annotated, you must use --tag-name-filter (and must not have + restored from refs/original/ in a previously botched rewrite). + +* Any commit messages that specify an encoding will become corrupted + by the rewrite; git-filter-branch ignores the encoding, takes the + original bytes, and feeds it to commit-tree without telling it the + proper encoding. (This happens whether or not --msg-filter is + used.) + +* Commit messages (even if they are all UTF-8) by default become + corrupted due to not being updated -- any references to other commit + hashes in commit messages will now refer to no-longer-extant + commits. + +* There are no facilities for helping users find what unwanted crud + they should delete, which means they are much more likely to have + incomplete or partial cleanups that sometimes result in confusion + and people wasting time trying to understand. (For example, folks + tend to just look for big files to delete instead of big directories + or extensions, and once they do so, then sometime later folks using + the new repository who are going through history will notice a build + artifact directory that has some files but not others, or a cache of + dependencies (node_modules or similar) which couldn't have ever been + functional since it's missing some files.) + +* If --prune-empty isn't specified, then the filtering process can + create hoards of confusing empty commits + +* If --prune-empty is specified, then intentionally placed empty + commits from before the filtering operation are also pruned instead + of just pruning commits that became empty due to filtering rules. + +* If --prune-empty is specified, sometimes empty commits are missed + and left around anyway (a somewhat rare bug, but it happens...) + +* A minor issue, but users who have a goal to update all names and + emails in a repository may be led to --env-filter which will only + update authors and committers, missing taggers. + +* If the user provides a --tag-name-filter that maps multiple tags to + the same name, no warning or error is provided; git-filter-branch + simply overwrites each tag in some undocumented pre-defined order + resulting in only one tag at the end. (A git-filter-branch + regression test requires this surprising behavior.) + +Also, the poor performance of git-filter-branch often leads to safety +issues: + +* Coming up with the correct shell snippet to do the filtering you + want is sometimes difficult unless you're just doing a trivial + modification such as deleting a couple files. Unfortunately, people + often learn if the snippet is right or wrong by trying it out, but + the rightness or wrongness can vary depending on special + circumstances (spaces in filenames, non-ascii filenames, funny + author names or emails, invalid timezones, presence of grafts or + replace objects, etc.), meaning they may have to wait a long time, + hit an error, then restart. The performance of git-filter-branch is + so bad that this cycle is painful, reducing the time available to + carefully re-check (to say nothing about what it does to the + patience of the person doing the rewrite even if they do technically + have more time available). This problem is extra compounded because + errors from broken filters may not be shown for a long time and/or + get lost in a sea of output. Even worse, broken filters often just + result in silent incorrect rewrites. + +* To top it all off, even when users finally find working commands, + they naturally want to share them. But they may be unaware that + their repo didn't have some special cases that someone else's does. + So, when someone else with a different repository runs the same + commands, they get hit by the problems above. Or, the user just + runs commands that really were vetted for special cases, but they + run it on a different OS where it doesn't work, as noted above. GIT --- diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index 774cecc7ed..6da899c629 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -11,7 +11,7 @@ SYNOPSIS 'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl] [(--sort=<key>)...] [--format=<format>] [<pattern>...] [--points-at=<object>] - (--merged[=<object>] | --no-merged[=<object>]) + [--merged[=<object>]] [--no-merged[=<object>]] [--contains[=<object>]] [--no-contains[=<object>]] DESCRIPTION @@ -76,13 +76,11 @@ OPTIONS --merged[=<object>]:: Only list refs whose tips are reachable from the - specified commit (HEAD if not specified), - incompatible with `--no-merged`. + specified commit (HEAD if not specified). --no-merged[=<object>]:: Only list refs whose tips are not reachable from the - specified commit (HEAD if not specified), - incompatible with `--merged`. + specified commit (HEAD if not specified). --contains[=<object>]:: Only list refs which contain the specified commit (HEAD if not @@ -214,9 +212,16 @@ symref:: `:lstrip` and `:rstrip` options in the same way as `refname` above. +worktreepath:: + The absolute path to the worktree in which the ref is checked + out, if it is checked out in any linked worktree. Empty string + otherwise. + In addition to the above, for commit and tag objects, the header field names (`tree`, `parent`, `object`, `type`, and `tag`) can be used to specify the value in the header field. +Fields `tree` and `parent` can also be used with modifier `:short` and +`:short=<length>` just like `objectname`. For commit and tag objects, the special `creatordate` and `creator` fields will correspond to the appropriate date or name-email-date tuple @@ -225,20 +230,48 @@ These are intended for working on a mix of annotated and lightweight tags. Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, -and `date` to extract the named component. - -The complete message in a commit and tag object is `contents`. -Its first line is `contents:subject`, where subject is the concatenation -of all lines of the commit message up to the first blank line. The next -line is `contents:body`, where body is all of the lines after the first -blank line. The optional GPG signature is `contents:signature`. The -first `N` lines of the message is obtained using `contents:lines=N`. +and `date` to extract the named component. For email fields (`authoremail`, +`committeremail` and `taggeremail`), `:trim` can be appended to get the email +without angle brackets, and `:localpart` to get the part before the `@` symbol +out of the trimmed email. + +The raw data in an object is `raw`. + +raw:size:: + The raw data size of the object. + +Note that `--format=%(raw)` can not be used with `--python`, `--shell`, `--tcl`, +because such language may not support arbitrary binary data in their string +variable type. + +The message in a commit or a tag object is `contents`, from which +`contents:<part>` can be used to extract various parts out of: + +contents:size:: + The size in bytes of the commit or tag message. + +contents:subject:: + The first paragraph of the message, which typically is a + single line, is taken as the "subject" of the commit or the + tag message. + Instead of `contents:subject`, field `subject` can also be used to + obtain same results. `:sanitize` can be appended to `subject` for + subject line suitable for filename. + +contents:body:: + The remainder of the commit or the tag message that follows + the "subject". + +contents:signature:: + The optional GPG signature of the tag. + +contents:lines=N:: + The first `N` lines of the message. + Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1] -are obtained as `trailers` (or by using the historical alias -`contents:trailers`). Non-trailer lines from the trailer block can be omitted -with `trailers:only`. Whitespace-continuations can be removed from trailers so -that each trailer appears on a line by itself with its full content with -`trailers:unfold`. Both can be used together as `trailers:unfold,only`. +are obtained as `trailers[:options]` (or by using the historical alias +`contents:trailers[:options]`). For valid [:option] values see `trailers` +section of linkgit:git-log[1]. For sorting purposes, fields with numeric values sort in numeric order (`objectsize`, `authordate`, `committerdate`, `creatordate`, `taggerdate`). @@ -380,6 +413,11 @@ 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. +NOTES +----- + +include::ref-reachability-filters.txt[] + SEE ALSO -------- linkgit:git-show-ref[1] diff --git a/Documentation/git-for-each-repo.txt b/Documentation/git-for-each-repo.txt new file mode 100644 index 0000000000..94bd19da26 --- /dev/null +++ b/Documentation/git-for-each-repo.txt @@ -0,0 +1,59 @@ +git-for-each-repo(1) +==================== + +NAME +---- +git-for-each-repo - Run a Git command on a list of repositories + + +SYNOPSIS +-------- +[verse] +'git for-each-repo' --config=<config> [--] <arguments> + + +DESCRIPTION +----------- +Run a Git command on a list of repositories. The arguments after the +known options or `--` indicator are used as the arguments for the Git +subprocess. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +For example, we could run maintenance on each of a list of repositories +stored in a `maintenance.repo` config variable using + +------------- +git for-each-repo --config=maintenance.repo maintenance run +------------- + +This will run `git -C <repo> maintenance run` for each value `<repo>` +in the multi-valued config variable `maintenance.repo`. + + +OPTIONS +------- +--config=<config>:: + Use the given config variable as a multi-valued list storing + absolute path names. Iterate on that list of paths to run + the given arguments. ++ +These config values are loaded from system, global, and local Git config, +as available. If `git for-each-repo` is run in a directory that is not a +Git repository, then only the system and global config is used. + + +SUBPROCESS BEHAVIOR +------------------- + +If any `git -C <repo> <arguments>` subprocess returns a non-zero exit code, +then the `git for-each-repo` process returns that exit code without running +more subprocesses. + +Each `git -C <repo> <arguments>` subprocess inherits the standard file +descriptors `stdin`, `stdout`, and `stderr`. + + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 1af85d404f..fe2f69d36e 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -17,14 +17,18 @@ SYNOPSIS [--signature-file=<file>] [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] - [--in-reply-to=Message-Id] [--suffix=.<sfx>] + [--in-reply-to=<message id>] [--suffix=.<sfx>] [--ignore-if-in-upstream] - [--rfc] [--subject-prefix=Subject-Prefix] + [--cover-from-description=<mode>] + [--rfc] [--subject-prefix=<subject prefix>] [(--reroll-count|-v) <n>] [--to=<email>] [--cc=<email>] - [--[no-]cover-letter] [--quiet] [--notes[=<ref>]] + [--[no-]cover-letter] [--quiet] + [--[no-]encode-email-headers] + [--no-notes | --notes[=<ref>]] [--interdiff=<previous>] [--range-diff=<previous> [--creation-factor=<percent>]] + [--filename-max-length=<n>] [--progress] [<common diff options>] [ <since> | <revision range> ] @@ -32,11 +36,28 @@ SYNOPSIS DESCRIPTION ----------- -Prepare each commit with its patch in -one file per commit, formatted to resemble UNIX mailbox format. +Prepare each non-merge commit with its "patch" in +one "message" per commit, formatted to resemble a UNIX mailbox. The output of this command is convenient for e-mail submission or for use with 'git am'. +A "message" generated by the command consists of three parts: + +* A brief metadata header that begins with `From <commit>` + with a fixed `Mon Sep 17 00:00:00 2001` datestamp to help programs + like "file(1)" to recognize that the file is an output from this + command, fields that record the author identity, the author date, + and the title of the change (taken from the first paragraph of the + commit log message). + +* The second and subsequent paragraphs of the commit log message. + +* The "patch", which is the "diff -p --stat" output (see + linkgit:git-diff[1]) between the commit and its parent. + +The log message and the patch is separated by a line with a +three-dash line. + There are two ways to specify which commits to operate on. 1. A single commit, <since>, specifies that the commits leading @@ -65,7 +86,8 @@ they are created in the current working directory. The default path can be set with the `format.outputDirectory` configuration option. The `-o` option takes precedence over `format.outputDirectory`. To store patches in the current working directory even when -`format.outputDirectory` points elsewhere, use `-o .`. +`format.outputDirectory` points elsewhere, use `-o .`. All directory +components will be created. By default, the subject of a single patch is "[PATCH] " followed by the concatenation of lines from the commit message up to the first blank @@ -115,7 +137,7 @@ include::diff-options.txt[] -s:: --signoff:: - Add `Signed-off-by:` line to the commit message, using + Add a `Signed-off-by` trailer to the commit message, using the committer identity of yourself. See the signoff option in linkgit:git-commit[1] for more information. @@ -158,9 +180,9 @@ Beware that the default for 'git send-email' is to thread emails itself. If you want `git format-patch` to take care of threading, you will want to ensure that threading is disabled for `git send-email`. ---in-reply-to=Message-Id:: +--in-reply-to=<message id>:: Make the first mail (or all the mails with `--no-thread`) appear as a - reply to the given Message-Id, which avoids breaking threads to + reply to the given <message id>, which avoids breaking threads to provide a new patch series. --ignore-if-in-upstream:: @@ -170,12 +192,39 @@ will want to ensure that threading is disabled for `git send-email`. patches being generated, and any patch that matches is ignored. ---subject-prefix=<Subject-Prefix>:: +--cover-from-description=<mode>:: + Controls which parts of the cover letter will be automatically + populated using the branch's description. ++ +If `<mode>` is `message` or `default`, the cover letter subject will be +populated with placeholder text. The body of the cover letter will be +populated with the branch's description. This is the default mode when +no configuration nor command line option is specified. ++ +If `<mode>` is `subject`, the first paragraph of the branch description will +populate the cover letter subject. The remainder of the description will +populate the body of the cover letter. ++ +If `<mode>` is `auto`, if the first paragraph of the branch description +is greater than 100 bytes, then the mode will be `message`, otherwise +`subject` will be used. ++ +If `<mode>` is `none`, both the cover letter subject and body will be +populated with placeholder text. + +--subject-prefix=<subject prefix>:: Instead of the standard '[PATCH]' prefix in the subject - line, instead use '[<Subject-Prefix>]'. This + line, instead use '[<subject prefix>]'. This allows for useful naming of a patch series, and can be combined with the `--numbered` option. +--filename-max-length=<n>:: + Instead of the standard 64 bytes, chomp the generated output + filenames at around '<n>' bytes (too short a value will be + silently raised to a reasonable length). Defaults to the + value of the `format.filenameMaxLength` configuration + variable, or 64 if unconfigured. + --rfc:: Alias for `--subject-prefix="RFC PATCH"`. RFC means "Request For Comments"; use this when sending an experimental patch for @@ -189,6 +238,11 @@ will want to ensure that threading is disabled for `git send-email`. `--subject-prefix` option) has ` v<n>` appended to it. E.g. `--reroll-count=4` may produce `v4-0001-add-makefile.patch` file that has "Subject: [PATCH v4 1/20] Add makefile" in it. + `<n>` does not have to be an integer (e.g. "--reroll-count=4.4", + or "--reroll-count=4rev2" are allowed), but the downside of + using such a reroll-count is that the range-diff/interdiff + with the previous version does not state exactly which + version the new interation is compared against. --to=<email>:: Add a `To:` header to the email headers. This is in addition @@ -230,6 +284,13 @@ feeding the result to `git send-email`. containing the branch description, shortlog and the overall diffstat. You can fill in a description in the file before sending it out. +--encode-email-headers:: +--no-encode-email-headers:: + Encode email headers that have non-ASCII characters with + "Q-encoding" (described in RFC 2047), instead of outputting the + headers verbatim. Defaults to the value of the + `format.encodeEmailHeaders` configuration variable. + --interdiff=<previous>:: As a reviewer aid, insert an interdiff into the cover letter, or as commentary of the lone patch of a 1-patch series, showing @@ -263,6 +324,7 @@ material (this may change in the future). for details. --notes[=<ref>]:: +--no-notes:: Append the notes (see linkgit:git-notes[1]) for the commit after the three-dash line. + @@ -273,6 +335,9 @@ these explanations after `format-patch` has run but before sending, keeping them as Git notes allows them to be maintained between versions of the patch series (but see the discussion of the `notes.rewrite` configuration options in linkgit:git-notes[1] to use this workflow). ++ +The default is `--no-notes`, unless the `format.notes` configuration is +set. --[no-]signature=<signature>:: Add a signature to each message produced. Per RFC 3676 the signature @@ -306,10 +371,12 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. Output an all-zero hash in each patch's From header instead of the hash of the commit. ---base=<commit>:: +--[no-]base[=<commit>]:: Record the base tree information to identify the state the patch series applies to. See the BASE TREE INFORMATION section - below for details. + below for details. If <commit> is "auto", a base commit is + automatically chosen. The `--no-base` option overrides a + `format.useAutoBase` configuration. --root:: Treat the revision argument as a <revision range>, even if it @@ -325,8 +392,9 @@ CONFIGURATION ------------- You can specify extra mail header lines to be added to each message, defaults for the subject prefix and file suffix, number patches when -outputting more than one patch, add "To" or "Cc:" headers, configure -attachments, and sign off patches with configuration variables. +outputting more than one patch, add "To:" or "Cc:" headers, configure +attachments, change the patch output directory, and sign off patches +with configuration variables. ------------ [format] @@ -338,7 +406,9 @@ attachments, and sign off patches with configuration variables. cc = <email> attach [ = mime-boundary-string ] signOff = true - coverletter = auto + outputDirectory = <directory> + coverLetter = auto + coverFromDescription = auto ------------ @@ -421,8 +491,8 @@ One way to test if your MUA is set up correctly is: * Apply it: $ git fetch <project> master:test-apply - $ git checkout test-apply - $ git reset --hard + $ git switch test-apply + $ git restore --source=HEAD --staged --worktree :/ $ git am a.patch If it does not apply correctly, there can be various reasons. @@ -670,6 +740,14 @@ use it only when you know the recipient uses Git to apply your patch. $ git format-patch -3 ------------ +CAVEATS +------- + +Note that `format-patch` will omit merge commits from the output, even +if they are part of the requested range. A simple "patch" does not +include enough information for the receiving end to reproduce the same +merge commit. + SEE ALSO -------- linkgit:git-am[1], linkgit:git-send-email[1] diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index d72d15be5b..bd596619c0 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -129,14 +129,6 @@ using 'git commit-graph verify'. See linkgit:git-commit-graph[1]. Extracted Diagnostics --------------------- -expect dangling commits - potential heads - due to lack of head information:: - You haven't specified any nodes as heads so it won't be - possible to differentiate between un-parented commits and - root nodes. - -missing sha1 directory '<dir>':: - The directory holding the sha1 objects is missing. - unreachable <type> <object>:: The <type> object <object>, isn't actually referred to directly or indirectly in any of the trees or commits seen. This can diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index 247f765604..853967dea0 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -115,15 +115,16 @@ NOTES ----- 'git gc' tries very hard not to delete objects that are referenced -anywhere in your repository. In -particular, it will keep not only objects referenced by your current set -of branches and tags, but also objects referenced by the index, -remote-tracking branches, refs saved by 'git filter-branch' in -refs/original/, reflogs (which may reference commits in branches -that were later amended or rewound), and anything else in the refs/* namespace. -If you are expecting some objects to be deleted and they aren't, check -all of those locations and decide whether it makes sense in your case to -remove those references. +anywhere in your repository. In particular, it will keep not only +objects referenced by your current set of branches and tags, but also +objects referenced by the index, remote-tracking branches, reflogs +(which may reference commits in branches that were later amended or +rewound), and anything else in the refs/* namespace. Note that a note +(of the kind created by 'git notes') attached to an object does not +contribute in keeping the object alive. If you are expecting some +objects to be deleted and they aren't, check all of those locations +and decide whether it makes sense in your case to remove those +references. On the other hand, when 'git gc' runs concurrently with another process, there is a risk of it deleting an object that the other process is using diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 2d27969057..3d393fbac1 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -38,38 +38,6 @@ are lists of one or more search expressions separated by newline characters. An empty string as search expression matches all lines. -CONFIGURATION -------------- - -grep.lineNumber:: - If set to true, enable `-n` option by default. - -grep.column:: - If set to true, enable the `--column` option by default. - -grep.patternType:: - Set the default matching behavior. Using a value of 'basic', 'extended', - 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`, - `--fixed-strings`, or `--perl-regexp` option accordingly, while the - value 'default' will return to the default matching behavior. - -grep.extendedRegexp:: - If set to true, enable `--extended-regexp` option by default. This - option is ignored when the `grep.patternType` option is set to a value - other than 'default'. - -grep.threads:: - Number of grep worker threads to use. If unset (or set to 0), - 8 threads are used by default (for now). - -grep.fullName:: - If set to true, enable `--full-name` option by default. - -grep.fallbackToNoIndex:: - If set to true, fall back to git grep --no-index if git grep - is executed outside of a git repository. Defaults to false. - - OPTIONS ------- --cached:: @@ -93,10 +61,11 @@ OPTIONS with `--no-index`. --recurse-submodules:: - Recursively search in each submodule that has been initialized and + Recursively search in each submodule that is active and checked out in the repository. When used in combination with the <tree> option the prefix of all submodule output will be the name of - the parent project's <tree> object. + the parent project's <tree> object. This option has no effect + if `--no-index` is given. -a:: --text:: @@ -205,8 +174,10 @@ providing this option will cause it to die. -z:: --null:: - Output \0 instead of the character that normally follows a - file name. + Use \0 as the delimiter for pathnames in the output, and print + them verbatim. Without this option, pathnames with "unusual" + characters are quoted as explained for the configuration + variable core.quotePath (see linkgit:git-config[1]). -o:: --only-matching:: @@ -238,7 +209,7 @@ providing this option will cause it to die. --show-function:: Show the preceding line that contains the function name of the match, unless the matching line is a function name itself. - The name is determined in the same way as 'git diff' works out + The name is determined in the same way as `git diff` works out patch hunk headers (see 'Defining a custom hunk-header' in linkgit:gitattributes[5]). @@ -263,7 +234,9 @@ providing this option will cause it to die. Show the surrounding text from the previous line containing a function name up to the one before the next function name, effectively showing the whole function in which the match was - found. + found. The function names are determined in the same way as + `git diff` works out patch hunk headers (see 'Defining a + custom hunk-header' in linkgit:gitattributes[5]). --threads <num>:: Number of grep worker threads to use. @@ -271,6 +244,23 @@ providing this option will cause it to die. -f <file>:: Read patterns from <file>, one per line. ++ +Passing the pattern via <file> allows for providing a search pattern +containing a \0. ++ +Not all pattern types support patterns containing \0. Git will error +out if a given pattern type can't support such a pattern. The +`--perl-regexp` pattern type when compiled against the PCRE v2 backend +has the widest support for these types of patterns. ++ +In versions of Git before 2.23.0 patterns containing \0 would be +silently considered fixed. This was never documented, there were also +odd and undocumented interactions between e.g. non-ASCII patterns +containing \0 and `--ignore-case`. ++ +In future versions we may learn to support patterns containing \0 for +more search backends, until then we'll die when the pattern type in +question doesn't support them. -e:: The next parameter is the pattern. This option has to be @@ -330,6 +320,49 @@ EXAMPLES `git grep solution -- :^Documentation`:: Looks for `solution`, excluding files in `Documentation`. +NOTES ON THREADS +---------------- + +The `--threads` option (and the grep.threads configuration) will be ignored when +`--open-files-in-pager` is used, forcing a single-threaded execution. + +When grepping the object store (with `--cached` or giving tree objects), running +with multiple threads might perform slower than single threaded if `--textconv` +is given and there're too many text conversions. So if you experience low +performance in this case, it might be desirable to use `--threads=1`. + +CONFIGURATION +------------- + +grep.lineNumber:: + If set to true, enable `-n` option by default. + +grep.column:: + If set to true, enable the `--column` option by default. + +grep.patternType:: + Set the default matching behavior. Using a value of 'basic', 'extended', + 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`, + `--fixed-strings`, or `--perl-regexp` option accordingly, while the + value 'default' will return to the default matching behavior. + +grep.extendedRegexp:: + If set to true, enable `--extended-regexp` option by default. This + option is ignored when the `grep.patternType` option is set to a value + other than 'default'. + +grep.threads:: + Number of grep worker threads to use. If unset (or set to 0), Git will + use as many threads as the number of logical cores available. + +grep.fullName:: + If set to true, enable `--full-name` option by default. + +grep.fallbackToNoIndex:: + If set to true, fall back to git grep --no-index if git grep + is executed outside of a git repository. Defaults to false. + + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.txt index 5f93f8003d..c9d7e96214 100644 --- a/Documentation/git-gui.txt +++ b/Documentation/git-gui.txt @@ -112,15 +112,9 @@ Other versions are distributed as part of the Git suite for the convenience of end users. -A 'git gui' development repository can be obtained from: +The official repository of the 'git gui' project can be found at: - git clone git://repo.or.cz/git-gui.git - -or - - git clone http://repo.or.cz/r/git-gui.git - -or browsed online at http://repo.or.cz/w/git-gui.git/[]. + https://github.com/prati0100/git-gui.git/ GIT --- diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index f71db0daa2..44fe8860b3 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -8,7 +8,7 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all [--[no-]verbose]] [-g|--guide] +'git help' [-a|--all [--[no-]verbose]] [-g|--guides] [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE] DESCRIPTION @@ -21,8 +21,8 @@ on the standard output. If the option `--all` or `-a` is given, all available commands are printed on the standard output. -If the option `--guide` or `-g` is given, a list of the useful -Git guides is also printed on the standard output. +If the option `--guides` or `-g` is given, a list of the +Git concept guides is also printed on the standard output. If a command, or a guide, is given, a manual page for that command or guide is brought up. The 'man' program is used by default for this @@ -58,7 +58,7 @@ OPTIONS -g:: --guides:: - Prints a list of useful guides on the standard output. This + Prints a list of the Git concept guides on the standard output. This option overrides any given command or guide name. -i:: diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.txt index 666b042679..9fa17b60e4 100644 --- a/Documentation/git-http-fetch.txt +++ b/Documentation/git-http-fetch.txt @@ -9,7 +9,7 @@ git-http-fetch - Download from a remote Git repository via HTTP SYNOPSIS -------- [verse] -'git http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin] <commit> <url> +'git http-fetch' [-c] [-t] [-a] [-d] [-v] [-w filename] [--recover] [--stdin | --packfile=<hash> | <commit>] <url> DESCRIPTION ----------- @@ -40,6 +40,19 @@ commit-id:: <commit-id>['\t'<filename-as-in--w>] +--packfile=<hash>:: + For internal use only. Instead of a commit id on the command + line (which is not expected in + this case), 'git http-fetch' fetches the packfile directly at the given + URL and uses index-pack to generate corresponding .idx and .keep files. + The hash is used to determine the name of the temporary file and is + arbitrary. The output of index-pack is printed to stdout. Requires + --index-pack-args. + +--index-pack-args=<args>:: + For internal use only. The command to run on the contents of the + downloaded pack. Arguments are URL-encoded separated by spaces. + --recover:: Verify that everything reachable from target is fetched. Used after an earlier fetch is interrupted. diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt index 65b53fcc47..63cf498ce9 100644 --- a/Documentation/git-imap-send.txt +++ b/Documentation/git-imap-send.txt @@ -51,17 +51,13 @@ OPTIONS CONFIGURATION ------------- -To use the tool, imap.folder and either imap.tunnel or imap.host must be set +To use the tool, `imap.folder` and either `imap.tunnel` or `imap.host` must be set to appropriate values. -Variables -~~~~~~~~~ - include::config/imap.txt[] -Examples -~~~~~~~~ - +EXAMPLES +-------- Using tunnel mode: .......................... @@ -89,14 +85,18 @@ Using direct mode with SSL: user = bob pass = p4ssw0rd port = 123 - sslverify = false + ; sslVerify = false ......................... -EXAMPLES --------- -To submit patches using GMail's IMAP interface, first, edit your ~/.gitconfig -to specify your account settings: +[NOTE] +You may want to use `sslVerify=false` +while troubleshooting, if you suspect that the reason you are +having trouble connecting is because the certificate you use at +the private server `example.com` you are trying to set up (or +have set up) may not be verified correctly. + +Using Gmail's IMAP interface: --------- [imap] @@ -104,17 +104,21 @@ to specify your account settings: host = imaps://imap.gmail.com user = user@gmail.com port = 993 - sslverify = false --------- -You might need to instead use: folder = "[Google Mail]/Drafts" if you get an error +[NOTE] +You might need to instead use: `folder = "[Google Mail]/Drafts"` if you get an error that the "Folder doesn't exist". +[NOTE] +If your Gmail account is set to another language than English, the name of the "Drafts" +folder will be localized. + Once the commits are ready to be sent, run the following command: $ git format-patch --cover-letter -M --stdout origin/master | git imap-send -Just make sure to disable line wrapping in the email client (GMail's web +Just make sure to disable line wrapping in the email client (Gmail's web interface will wrap lines no matter what, so you need to use a real IMAP client). diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.txt index d5b7560bfe..7fa74b9e79 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.txt @@ -9,17 +9,18 @@ git-index-pack - Build pack index file for an existing packed archive SYNOPSIS -------- [verse] -'git index-pack' [-v] [-o <index-file>] <pack-file> +'git index-pack' [-v] [-o <index-file>] [--[no-]rev-index] <pack-file> 'git index-pack' --stdin [--fix-thin] [--keep] [-v] [-o <index-file>] - [<pack-file>] + [--[no-]rev-index] [<pack-file>] DESCRIPTION ----------- Reads a packed archive (.pack) from the specified file, and -builds a pack index file (.idx) for it. The packed archive -together with the pack index can then be placed in the -objects/pack/ directory of a Git repository. +builds a pack index file (.idx) for it. Optionally writes a +reverse-index (.rev) for the specified pack. The packed +archive together with the pack index can then be placed in +the objects/pack/ directory of a Git repository. OPTIONS @@ -35,6 +36,13 @@ OPTIONS fails if the name of packed archive does not end with .pack). +--[no-]rev-index:: + When this flag is provided, generate a reverse index + (a `.rev` file) corresponding to the given pack. If + `--verify` is given, ensure that the existing + reverse index is correct. Takes precedence over + `pack.writeReverseIndex`. + --stdin:: When this flag is provided, the pack is read from stdin instead and a copy is then written to <pack-file>. If @@ -78,7 +86,12 @@ OPTIONS Die if the pack contains broken links. For internal use only. --fsck-objects:: - Die if the pack contains broken objects. For internal use only. + For internal use only. ++ +Die if the pack contains broken objects. If the pack contains a tree +pointing to a .gitmodules blob that does not exist, prints the hash of +that blob (for the caller to check) after the hash that goes into the +name of the pack/idx file (see "Notes"). --threads=<n>:: Specifies the number of threads to spawn when resolving @@ -93,11 +106,21 @@ OPTIONS --max-input-size=<size>:: Die, if the pack is larger than <size>. +--object-format=<hash-algorithm>:: + Specify the given object format (hash algorithm) for the pack. The valid + values are 'sha1' and (if enabled) 'sha256'. The default is the algorithm for + the current repository (set by `extensions.objectFormat`), or 'sha1' if no + value is set or outside a repository. ++ +This option cannot be used with --stdin. ++ +include::object-format-disclaimer.txt[] + NOTES ----- -Once the index has been created, the list of object names is sorted -and the SHA-1 hash of that list is printed to stdout. If --stdin was +Once the index has been created, the hash that goes into the name of +the pack/idx file is printed to stdout. If --stdin was also used then this is prefixed by either "pack\t", or "keep\t" if a new .keep file was successfully created. This is useful to remove a .keep file used as a lock to prevent the race with 'git repack' diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 32880aafb0..b611d80697 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -10,7 +10,8 @@ SYNOPSIS -------- [verse] 'git init' [-q | --quiet] [--bare] [--template=<template_directory>] - [--separate-git-dir <git dir>] + [--separate-git-dir <git dir>] [--object-format=<format>] + [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [directory] @@ -19,8 +20,9 @@ DESCRIPTION This command creates an empty Git repository - basically a `.git` directory with subdirectories for `objects`, `refs/heads`, -`refs/tags`, and template files. An initial `HEAD` file that -references the HEAD of the master branch is also created. +`refs/tags`, and template files. An initial branch without any +commits will be created (see the `--initial-branch` option below +for its name). If the `$GIT_DIR` environment variable is set then it specifies a path to use instead of `./.git` for the base of the repository. @@ -48,6 +50,13 @@ Only print error and warning messages; all other output will be suppressed. Create a bare repository. If `GIT_DIR` environment is not set, it is set to the current working directory. +--object-format=<format>:: + +Specify the given object format (hash algorithm) for the repository. The valid +values are 'sha1' and (if enabled) 'sha256'. 'sha1' is the default. ++ +include::object-format-disclaimer.txt[] + --template=<template_directory>:: Specify the directory from which templates will be used. (See the "TEMPLATE @@ -62,6 +71,14 @@ repository. + If this is reinitialization, the repository will be moved to the specified path. +-b <branch-name>:: +--initial-branch=<branch-name>:: + +Use the specified name for the initial branch in the newly created +repository. If not specified, fall back to the default name (currently +`master`, but this is subject to change in the future; the name can be +customized via the `init.defaultBranch` configuration variable). + --shared[=(false|true|umask|group|all|world|everybody|0xxx)]:: Specify that the Git repository is to be shared amongst several users. This diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt index 96ec6499f0..956a01d184 100644 --- a/Documentation/git-interpret-trailers.txt +++ b/Documentation/git-interpret-trailers.txt @@ -232,25 +232,38 @@ trailer.<token>.ifmissing:: that option for trailers with the specified <token>. trailer.<token>.command:: - This option can be used to specify a shell command that will - be called to automatically add or modify a trailer with the - specified <token>. + This option behaves in the same way as 'trailer.<token>.cmd', except + that it doesn't pass anything as argument to the specified command. + Instead the first occurrence of substring $ARG is replaced by the + value that would be passed as argument. + -When this option is specified, the behavior is as if a special -'<token>=<value>' argument were added at the beginning of the command -line, where <value> is taken to be the standard output of the -specified command with any leading and trailing whitespace trimmed -off. +The 'trailer.<token>.command' option has been deprecated in favor of +'trailer.<token>.cmd' due to the fact that $ARG in the user's command is +only replaced once and that the original way of replacing $ARG is not safe. + -If the command contains the `$ARG` string, this string will be -replaced with the <value> part of an existing trailer with the same -<token>, if any, before the command is launched. +When both 'trailer.<token>.cmd' and 'trailer.<token>.command' are given +for the same <token>, 'trailer.<token>.cmd' is used and +'trailer.<token>.command' is ignored. + +trailer.<token>.cmd:: + This option can be used to specify a shell command that will be called: + once to automatically add a trailer with the specified <token>, and then + each time a '--trailer <token>=<value>' argument to modify the <value> of + the trailer that this option would produce. + -If some '<token>=<value>' arguments are also passed on the command -line, when a 'trailer.<token>.command' is configured, the command will -also be executed for each of these arguments. And the <value> part of -these arguments, if any, will be used to replace the `$ARG` string in -the command. +When the specified command is first called to add a trailer +with the specified <token>, the behavior is as if a special +'--trailer <token>=<value>' argument was added at the beginning +of the "git interpret-trailers" command, where <value> +is taken to be the standard output of the command with any +leading and trailing whitespace trimmed off. ++ +If some '--trailer <token>=<value>' arguments are also passed +on the command line, the command is called again once for each +of these arguments with the same <token>. And the <value> part +of these arguments, if any, will be passed to the command as its +first argument. This way the command can produce a <value> computed +from the <value> passed in the '--trailer <token>=<value>' argument. EXAMPLES -------- @@ -333,6 +346,55 @@ subject Fix #42 ------------ +* Configure a 'help' trailer with a cmd use a script `glog-find-author` + which search specified author identity from git log in git repository + and show how it works: ++ +------------ +$ cat ~/bin/glog-find-author +#!/bin/sh +test -n "$1" && git log --author="$1" --pretty="%an <%ae>" -1 || true +$ git config trailer.help.key "Helped-by: " +$ git config trailer.help.ifExists "addIfDifferentNeighbor" +$ git config trailer.help.cmd "~/bin/glog-find-author" +$ git interpret-trailers --trailer="help:Junio" --trailer="help:Couder" <<EOF +> subject +> +> message +> +> EOF +subject + +message + +Helped-by: Junio C Hamano <gitster@pobox.com> +Helped-by: Christian Couder <christian.couder@gmail.com> +------------ + +* Configure a 'ref' trailer with a cmd use a script `glog-grep` + to grep last relevant commit from git log in the git repository + and show how it works: ++ +------------ +$ cat ~/bin/glog-grep +#!/bin/sh +test -n "$1" && git log --grep "$1" --pretty=reference -1 || true +$ git config trailer.ref.key "Reference-to: " +$ git config trailer.ref.ifExists "replace" +$ git config trailer.ref.cmd "~/bin/glog-grep" +$ git interpret-trailers --trailer="ref:Add copyright notices." <<EOF +> subject +> +> message +> +> EOF +subject + +message + +Reference-to: 8bc9a0c769 (Add copyright notices., 2005-04-07) +------------ + * Configure a 'see' trailer with a command to show the subject of a commit that is related, and show how it works: + diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index b02e922dc3..0498e7bacb 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -15,9 +15,12 @@ DESCRIPTION ----------- Shows the commit logs. -The command takes options applicable to the `git rev-list` +:git-log: 1 +include::rev-list-description.txt[] + +The command takes options applicable to the linkgit:git-rev-list[1] command to control what is shown and how, and options applicable to -the `git diff-*` commands to control how the changes +the linkgit:git-diff[1] command to control how the changes each commit introduces are shown. @@ -36,20 +39,26 @@ OPTIONS full ref name (including prefix) will be printed. If 'auto' is specified, then if the output is going to a terminal, the ref names are shown as if 'short' were given, otherwise no ref names are - shown. The default option is 'short'. + shown. The option `--decorate` is short-hand for `--decorate=short`. + Default to configuration value of `log.decorate` if configured, + otherwise, `auto`. --decorate-refs=<pattern>:: --decorate-refs-exclude=<pattern>:: If no `--decorate-refs` is given, pretend as if all refs were included. For each candidate, do not use it for decoration if it matches any patterns given to `--decorate-refs-exclude` or if it - doesn't match any of the patterns given to `--decorate-refs`. + doesn't match any of the patterns given to `--decorate-refs`. The + `log.excludeDecoration` config option allows excluding refs from + the decorations, but an explicit `--decorate-refs` pattern will + override a match in `log.excludeDecoration`. --source:: Print out the ref name given on the command line by which each commit was reached. ---use-mailmap:: +--[no-]mailmap:: +--[no-]use-mailmap:: Use mailmap file to map author and committer names and email addresses to canonical real names and email addresses. See linkgit:git-shortlog[1]. @@ -70,16 +79,7 @@ produced by `--stat`, etc. Intended to speed up tools that read log messages from `git log` output by allowing them to allocate space in advance. --L <start>,<end>:<file>:: --L :<funcname>:<file>:: - Trace the evolution of the line range given by "<start>,<end>" - (or the function name regex <funcname>) within the <file>. You may - not give any pathspec limiters. This is currently limited to - a walk starting from a single revision, i.e., you may only - give zero or one positive revision arguments. - You can specify this option more than once. -+ -include::line-range-format.txt[] +include::line-range-options.txt[] <revision range>:: Show only commits in the specified revision range. When no @@ -103,10 +103,21 @@ include::rev-list-options.txt[] include::pretty-formats.txt[] -COMMON DIFF OPTIONS -------------------- +DIFF FORMATTING +--------------- + +By default, `git log` does not generate any diff output. The options +below can be used to show the changes made by each commit. + +Note that unless one of `--diff-merges` variants (including short +`-m`, `-c`, and `--cc` options) is explicitly given, merge commits +will not show a diff, even if a diff format like `--patch` is +selected, nor will they match search options like `-S`. The exception +is when `--first-parent` is in use, in which case `first-parent` is +the default format. :git-log: 1 +:diff-merges-default: `off` include::diff-options.txt[] include::diff-generate-patch.txt[] diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index 8461c0e83e..6d11ab506b 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -13,19 +13,19 @@ SYNOPSIS (--[cached|deleted|others|ignored|stage|unmerged|killed|modified])* (-[c|d|o|i|s|u|k|m])* [--eol] + [--deduplicate] [-x <pattern>|--exclude=<pattern>] [-X <file>|--exclude-from=<file>] [--exclude-per-directory=<file>] [--exclude-standard] [--error-unmatch] [--with-tree=<tree-ish>] [--full-name] [--recurse-submodules] - [--abbrev] [--] [<file>...] + [--abbrev[=<n>]] [--] [<file>...] DESCRIPTION ----------- -This merges the file listing in the directory cache index with the -actual working directory list, and shows different combinations of the -two. +This merges the file listing in the index with the actual working +directory list, and shows different combinations of the two. One or more of the options below may be used to determine the files shown: @@ -81,6 +81,13 @@ OPTIONS \0 line termination on output and do not quote filenames. See OUTPUT below for more information. +--deduplicate:: + When only filenames are shown, suppress duplicates that may + come from having multiple stages during a merge, or giving + `--deleted` and `--modified` option at the same time. + When any of the `-t`, `--unmerged`, or `--stage` option is + in use, this option has no effect. + -x <pattern>:: --exclude=<pattern>:: Skip untracked files matching pattern. @@ -148,12 +155,13 @@ a space) at the start of each line: top directory. --recurse-submodules:: - Recursively calls ls-files on each submodule in the repository. + Recursively calls ls-files on each active submodule in the repository. Currently there is only support for the --cached mode. --abbrev[=<n>]:: Instead of showing the full 40-byte hexadecimal object - lines, show only a partial prefix. + lines, show the shortest prefix that is at least '<n>' + hexdigits long that uniquely refers the object. Non default number of digits can be specified with --abbrev=<n>. --debug:: diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt index 0b057cbb10..492e573856 100644 --- a/Documentation/git-ls-remote.txt +++ b/Documentation/git-ls-remote.txt @@ -28,7 +28,9 @@ OPTIONS Limit to only refs/heads and refs/tags, respectively. These options are _not_ mutually exclusive; when given both, references stored in refs/heads and refs/tags are - displayed. + displayed. Note that `git ls-remote -h` used without + anything else on the command line gives help, consistent + with other git subcommands. --refs:: Do not show peeled tags or pseudorefs like `HEAD` in the output. @@ -92,21 +94,23 @@ OPTIONS EXAMPLES -------- - $ git ls-remote --tags ./. - d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99 - f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1 - 7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3 - c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2 - 0918385dbd9656cab0d1d81ba7453d49bbc16250 refs/tags/junio-gpg-pub - $ git ls-remote http://www.kernel.org/pub/scm/git/git.git master pu rc - 5fe978a5381f1fbad26a80e682ddd2a401966740 refs/heads/master - c781a84b5204fb294c9ccc79f8b3baceeb32c061 refs/heads/pu - $ git remote add korg http://www.kernel.org/pub/scm/git/git.git - $ git ls-remote --tags korg v\* - d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99 - f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1 - c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2 - 7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3 +---- +$ git ls-remote --tags ./. +d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99 +f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1 +7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3 +c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2 +0918385dbd9656cab0d1d81ba7453d49bbc16250 refs/tags/junio-gpg-pub +$ git ls-remote http://www.kernel.org/pub/scm/git/git.git master seen rc +5fe978a5381f1fbad26a80e682ddd2a401966740 refs/heads/master +c781a84b5204fb294c9ccc79f8b3baceeb32c061 refs/heads/seen +$ git remote add korg http://www.kernel.org/pub/scm/git/git.git +$ git ls-remote --tags korg v\* +d6602ec5194c87b0fc87103ca4d67251c76f233a refs/tags/v0.99 +f25a265a342aed6041ab0cc484224d9ca54b6f41 refs/tags/v0.99.1 +c5db5456ae3b0873fc659c19fafdde22313cc441 refs/tags/v0.99.2 +7ceca275d047c90c0c7d5afb13ab97efdf51bd6e refs/tags/v0.99.3 +---- SEE ALSO -------- diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt index a7515714da..db02d6d79a 100644 --- a/Documentation/git-ls-tree.txt +++ b/Documentation/git-ls-tree.txt @@ -62,7 +62,8 @@ OPTIONS --abbrev[=<n>]:: Instead of showing the full 40-byte hexadecimal object - lines, show only a partial prefix. + lines, show the shortest prefix that is at least '<n>' + hexdigits long that uniquely refers the object. Non default number of digits can be specified with --abbrev=<n>. --full-name:: diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 3bbc731f67..3fcfd965fd 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -9,7 +9,9 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message SYNOPSIS -------- [verse] -'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--[no-]scissors] <msg> <patch> +'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] + [--[no-]scissors] [--quoted-cr=<action>] + <msg> <patch> DESCRIPTION @@ -53,7 +55,7 @@ character. The commit log message, author name and author email are taken from the e-mail, and after minimally decoding MIME transfer encoding, re-coded in the charset specified by - i18n.commitencoding (defaulting to UTF-8) by transliterating + `i18n.commitEncoding` (defaulting to UTF-8) by transliterating them. This used to be optional but now it is the default. + Note that the patch is always used as-is without charset @@ -61,7 +63,7 @@ conversion, even with this flag. --encoding=<encoding>:: Similar to -u. But when re-coding, the charset specified here is - used instead of the one specified by i18n.commitencoding or UTF-8. + used instead of the one specified by `i18n.commitEncoding` or UTF-8. -n:: Disable all charset re-coding of the metadata. @@ -72,10 +74,9 @@ conversion, even with this flag. is useful in order to associate commits with mailing list discussions. --scissors:: - Remove everything in body before a scissors line. A line that - mainly consists of scissors (either ">8" or "8<") and perforation - (dash "-") marks is called a scissors line, and is used to request - the reader to cut the message at that line. If such a line + Remove everything in body before a scissors line (e.g. "-- >8 --"). + The line represents scissors and perforation marks, and is used to + request the reader to cut the message at that line. If that line appears in the body of the message before the patch, everything before it (including the scissors line itself) is ignored when this option is used. @@ -90,6 +91,23 @@ This can be enabled by default with the configuration option mailinfo.scissors. --no-scissors:: Ignore scissors lines. Useful for overriding mailinfo.scissors settings. +--quoted-cr=<action>:: + Action when processes email messages sent with base64 or + quoted-printable encoding, and the decoded lines end with a CRLF + instead of a simple LF. ++ +The valid actions are: ++ +-- +* `nowarn`: Git will do nothing when such a CRLF is found. +* `warn`: Git will issue a warning for each message if such a CRLF is + found. +* `strip`: Git will convert those CRLF to LF. +-- ++ +The default action could be set by configuration option `mailinfo.quotedCR`. +If no such configuration option has been set, `warn` will be used. + <msg>:: The commit log message extracted from e-mail, usually except the title line which comes from e-mail Subject. diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt new file mode 100644 index 0000000000..1e738ad398 --- /dev/null +++ b/Documentation/git-maintenance.txt @@ -0,0 +1,344 @@ +git-maintenance(1) +================== + +NAME +---- +git-maintenance - Run tasks to optimize Git repository data + + +SYNOPSIS +-------- +[verse] +'git maintenance' run [<options>] + + +DESCRIPTION +----------- +Run tasks to optimize Git repository data, speeding up other Git commands +and reducing storage requirements for the repository. + +Git commands that add repository data, such as `git add` or `git fetch`, +are optimized for a responsive user experience. These commands do not take +time to optimize the Git data, since such optimizations scale with the full +size of the repository while these user commands each perform a relatively +small action. + +The `git maintenance` command provides flexibility for how to optimize the +Git repository. + +SUBCOMMANDS +----------- + +register:: + Initialize Git config values so any scheduled maintenance will + start running on this repository. This adds the repository to the + `maintenance.repo` config variable in the current user's global + config and enables some recommended configuration values for + `maintenance.<task>.schedule`. The tasks that are enabled are safe + for running in the background without disrupting foreground + processes. ++ +The `register` subcommand will also set the `maintenance.strategy` config +value to `incremental`, if this value is not previously set. The +`incremental` strategy uses the following schedule for each maintenance +task: ++ +-- +* `gc`: disabled. +* `commit-graph`: hourly. +* `prefetch`: hourly. +* `loose-objects`: daily. +* `incremental-repack`: daily. +-- ++ +`git maintenance register` will also disable foreground maintenance by +setting `maintenance.auto = false` in the current repository. This config +setting will remain after a `git maintenance unregister` command. + +run:: + Run one or more maintenance tasks. If one or more `--task` options + are specified, then those tasks are run in that order. Otherwise, + the tasks are determined by which `maintenance.<task>.enabled` + config options are true. By default, only `maintenance.gc.enabled` + is true. + +start:: + Start running maintenance on the current repository. This performs + the same config updates as the `register` subcommand, then updates + the background scheduler to run `git maintenance run --scheduled` + on an hourly basis. + +stop:: + Halt the background maintenance schedule. The current repository + is not removed from the list of maintained repositories, in case + the background maintenance is restarted later. + +unregister:: + Remove the current repository from background maintenance. This + only removes the repository from the configured list. It does not + stop the background maintenance processes from running. + +TASKS +----- + +commit-graph:: + The `commit-graph` job updates the `commit-graph` files incrementally, + then verifies that the written data is correct. The incremental + write is safe to run alongside concurrent Git processes since it + will not expire `.graph` files that were in the previous + `commit-graph-chain` file. They will be deleted by a later run based + on the expiration delay. + +prefetch:: + The `prefetch` task updates the object directory with the latest + objects from all registered remotes. For each remote, a `git fetch` + command is run. The configured refspec is modified to place all + requested refs within `refs/prefetch/`. Also, tags are not updated. ++ +This is done to avoid disrupting the remote-tracking branches. The end users +expect these refs to stay unmoved unless they initiate a fetch. With prefetch +task, however, the objects necessary to complete a later real fetch would +already be obtained, so the real fetch would go faster. In the ideal case, +it will just become an update to a bunch of remote-tracking branches without +any object transfer. + +gc:: + Clean up unnecessary files and optimize the local repository. "GC" + stands for "garbage collection," but this task performs many + smaller tasks. This task can be expensive for large repositories, + as it repacks all Git objects into a single pack-file. It can also + be disruptive in some situations, as it deletes stale data. See + linkgit:git-gc[1] for more details on garbage collection in Git. + +loose-objects:: + The `loose-objects` job cleans up loose objects and places them into + pack-files. In order to prevent race conditions with concurrent Git + commands, it follows a two-step process. First, it deletes any loose + objects that already exist in a pack-file; concurrent Git processes + will examine the pack-file for the object data instead of the loose + object. Second, it creates a new pack-file (starting with "loose-") + containing a batch of loose objects. The batch size is limited to 50 + thousand objects to prevent the job from taking too long on a + repository with many loose objects. The `gc` task writes unreachable + objects as loose objects to be cleaned up by a later step only if + they are not re-added to a pack-file; for this reason it is not + advisable to enable both the `loose-objects` and `gc` tasks at the + same time. + +incremental-repack:: + The `incremental-repack` job repacks the object directory + using the `multi-pack-index` feature. In order to prevent race + conditions with concurrent Git commands, it follows a two-step + process. First, it calls `git multi-pack-index expire` to delete + pack-files unreferenced by the `multi-pack-index` file. Second, it + calls `git multi-pack-index repack` to select several small + pack-files and repack them into a bigger one, and then update the + `multi-pack-index` entries that refer to the small pack-files to + refer to the new pack-file. This prepares those small pack-files + for deletion upon the next run of `git multi-pack-index expire`. + The selection of the small pack-files is such that the expected + size of the big pack-file is at least the batch size; see the + `--batch-size` option for the `repack` subcommand in + linkgit:git-multi-pack-index[1]. The default batch-size is zero, + which is a special case that attempts to repack all pack-files + into a single pack-file. + +pack-refs:: + The `pack-refs` task collects the loose reference files and + collects them into a single file. This speeds up operations that + need to iterate across many references. See linkgit:git-pack-refs[1] + for more information. + +OPTIONS +------- +--auto:: + When combined with the `run` subcommand, run maintenance tasks + only if certain thresholds are met. For example, the `gc` task + runs when the number of loose objects exceeds the number stored + in the `gc.auto` config setting, or when the number of pack-files + exceeds the `gc.autoPackLimit` config setting. Not compatible with + the `--schedule` option. + +--schedule:: + When combined with the `run` subcommand, run maintenance tasks + only if certain time conditions are met, as specified by the + `maintenance.<task>.schedule` config value for each `<task>`. + This config value specifies a number of seconds since the last + time that task ran, according to the `maintenance.<task>.lastRun` + config value. The tasks that are tested are those provided by + the `--task=<task>` option(s) or those with + `maintenance.<task>.enabled` set to true. + +--quiet:: + Do not report progress or other information over `stderr`. + +--task=<task>:: + If this option is specified one or more times, then only run the + specified tasks in the specified order. If no `--task=<task>` + arguments are specified, then only the tasks with + `maintenance.<task>.enabled` configured as `true` are considered. + See the 'TASKS' section for the list of accepted `<task>` values. + + +TROUBLESHOOTING +--------------- +The `git maintenance` command is designed to simplify the repository +maintenance patterns while minimizing user wait time during Git commands. +A variety of configuration options are available to allow customizing this +process. The default maintenance options focus on operations that complete +quickly, even on large repositories. + +Users may find some cases where scheduled maintenance tasks do not run as +frequently as intended. Each `git maintenance run` command takes a lock on +the repository's object database, and this prevents other concurrent +`git maintenance run` commands from running on the same repository. Without +this safeguard, competing processes could leave the repository in an +unpredictable state. + +The background maintenance schedule runs `git maintenance run` processes +on an hourly basis. Each run executes the "hourly" tasks. At midnight, +that process also executes the "daily" tasks. At midnight on the first day +of the week, that process also executes the "weekly" tasks. A single +process iterates over each registered repository, performing the scheduled +tasks for that frequency. Depending on the number of registered +repositories and their sizes, this process may take longer than an hour. +In this case, multiple `git maintenance run` commands may run on the same +repository at the same time, colliding on the object database lock. This +results in one of the two tasks not running. + +If you find that some maintenance windows are taking longer than one hour +to complete, then consider reducing the complexity of your maintenance +tasks. For example, the `gc` task is much slower than the +`incremental-repack` task. However, this comes at a cost of a slightly +larger object database. Consider moving more expensive tasks to be run +less frequently. + +Expert users may consider scheduling their own maintenance tasks using a +different schedule than is available through `git maintenance start` and +Git configuration options. These users should be aware of the object +database lock and how concurrent `git maintenance run` commands behave. +Further, the `git gc` command should not be combined with +`git maintenance run` commands. `git gc` modifies the object database +but does not take the lock in the same way as `git maintenance run`. If +possible, use `git maintenance run --task=gc` instead of `git gc`. + +The following sections describe the mechanisms put in place to run +background maintenance by `git maintenance start` and how to customize +them. + +BACKGROUND MAINTENANCE ON POSIX SYSTEMS +--------------------------------------- + +The standard mechanism for scheduling background tasks on POSIX systems +is cron(8). This tool executes commands based on a given schedule. The +current list of user-scheduled tasks can be found by running `crontab -l`. +The schedule written by `git maintenance start` is similar to this: + +----------------------------------------------------------------------- +# BEGIN GIT MAINTENANCE SCHEDULE +# The following schedule was created by Git +# Any edits made in this region might be +# replaced in the future by a Git command. + +0 1-23 * * * "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=hourly +0 0 * * 1-6 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=daily +0 0 * * 0 "/<path>/git" --exec-path="/<path>" for-each-repo --config=maintenance.repo maintenance run --schedule=weekly + +# END GIT MAINTENANCE SCHEDULE +----------------------------------------------------------------------- + +The comments are used as a region to mark the schedule as written by Git. +Any modifications within this region will be completely deleted by +`git maintenance stop` or overwritten by `git maintenance start`. + +The `crontab` entry specifies the full path of the `git` executable to +ensure that the executed `git` command is the same one with which +`git maintenance start` was issued independent of `PATH`. If the same user +runs `git maintenance start` with multiple Git executables, then only the +latest executable is used. + +These commands use `git for-each-repo --config=maintenance.repo` to run +`git maintenance run --schedule=<frequency>` on each repository listed in +the multi-valued `maintenance.repo` config option. These are typically +loaded from the user-specific global config. The `git maintenance` process +then determines which maintenance tasks are configured to run on each +repository with each `<frequency>` using the `maintenance.<task>.schedule` +config options. These values are loaded from the global or repository +config values. + +If the config values are insufficient to achieve your desired background +maintenance schedule, then you can create your own schedule. If you run +`crontab -e`, then an editor will load with your user-specific `cron` +schedule. In that editor, you can add your own schedule lines. You could +start by adapting the default schedule listed earlier, or you could read +the crontab(5) documentation for advanced scheduling techniques. Please +do use the full path and `--exec-path` techniques from the default +schedule to ensure you are executing the correct binaries in your +schedule. + + +BACKGROUND MAINTENANCE ON MACOS SYSTEMS +--------------------------------------- + +While macOS technically supports `cron`, using `crontab -e` requires +elevated privileges and the executed process does not have a full user +context. Without a full user context, Git and its credential helpers +cannot access stored credentials, so some maintenance tasks are not +functional. + +Instead, `git maintenance start` interacts with the `launchctl` tool, +which is the recommended way to schedule timed jobs in macOS. Scheduling +maintenance through `git maintenance (start|stop)` requires some +`launchctl` features available only in macOS 10.11 or later. + +Your user-specific scheduled tasks are stored as XML-formatted `.plist` +files in `~/Library/LaunchAgents/`. You can see the currently-registered +tasks using the following command: + +----------------------------------------------------------------------- +$ ls ~/Library/LaunchAgents/org.git-scm.git* +org.git-scm.git.daily.plist +org.git-scm.git.hourly.plist +org.git-scm.git.weekly.plist +----------------------------------------------------------------------- + +One task is registered for each `--schedule=<frequency>` option. To +inspect how the XML format describes each schedule, open one of these +`.plist` files in an editor and inspect the `<array>` element following +the `<key>StartCalendarInterval</key>` element. + +`git maintenance start` will overwrite these files and register the +tasks again with `launchctl`, so any customizations should be done by +creating your own `.plist` files with distinct names. Similarly, the +`git maintenance stop` command will unregister the tasks with `launchctl` +and delete the `.plist` files. + +To create more advanced customizations to your background tasks, see +launchctl.plist(5) for more information. + + +BACKGROUND MAINTENANCE ON WINDOWS SYSTEMS +----------------------------------------- + +Windows does not support `cron` and instead has its own system for +scheduling background tasks. The `git maintenance start` command uses +the `schtasks` command to submit tasks to this system. You can inspect +all background tasks using the Task Scheduler application. The tasks +added by Git have names of the form `Git Maintenance (<frequency>)`. +The Task Scheduler GUI has ways to inspect these tasks, but you can also +export the tasks to XML files and view the details there. + +Note that since Git is a console application, these background tasks +create a console window visible to the current user. This can be changed +manually by selecting the "Run whether user is logged in or not" option +in Task Scheduler. This change requires a password input, which is why +`git maintenance start` does not select it by default. + +If you want to customize the background tasks, please rename the tasks +so future calls to `git maintenance (start|stop)` do not overwrite your +custom tasks. + + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt index 9f07f4f6ed..2d944e0851 100644 --- a/Documentation/git-merge-base.txt +++ b/Documentation/git-merge-base.txt @@ -80,9 +80,11 @@ which is reachable from both 'A' and 'B' through the parent relationship. For example, with this topology: - o---o---o---B - / - ---o---1---o---o---o---A +.... + o---o---o---B + / +---o---1---o---o---o---A +.... the merge base between 'A' and 'B' is '1'. @@ -90,21 +92,25 @@ Given three commits 'A', 'B' and 'C', `git merge-base A B C` will compute the merge base between 'A' and a hypothetical commit 'M', which is a merge between 'B' and 'C'. For example, with this topology: - o---o---o---o---C - / - / o---o---o---B - / / - ---2---1---o---o---o---A +.... + o---o---o---o---C + / + / o---o---o---B + / / +---2---1---o---o---o---A +.... the result of `git merge-base A B C` is '1'. This is because the equivalent topology with a merge commit 'M' between 'B' and 'C' is: - o---o---o---o---o - / \ - / o---o---o---o---M - / / - ---2---1---o---o---o---A +.... + o---o---o---o---o + / \ + / o---o---o---o---M + / / +---2---1---o---o---o---A +.... and the result of `git merge-base A M` is '1'. Commit '2' is also a common ancestor between 'A' and 'M', but '1' is a better common ancestor, @@ -116,11 +122,13 @@ the best common ancestor of all commits. When the history involves criss-cross merges, there can be more than one 'best' common ancestor for two commits. For example, with this topology: - ---1---o---A - \ / - X - / \ - ---2---o---o---B +.... +---1---o---A + \ / + X + / \ +---2---o---o---B +.... both '1' and '2' are merge-bases of A and B. Neither one is better than the other (both are 'best' merge bases). When the `--all` option is not given, @@ -131,36 +139,42 @@ and B is (or at least used to be) to compute the merge base between A and B, and check if it is the same as A, in which case, A is an ancestor of B. You will see this idiom used often in older scripts. - A=$(git rev-parse --verify A) - if test "$A" = "$(git merge-base A B)" - then - ... A is an ancestor of B ... - fi +.... +A=$(git rev-parse --verify A) +if test "$A" = "$(git merge-base A B)" +then + ... A is an ancestor of B ... +fi +.... In modern git, you can say this in a more direct way: - if git merge-base --is-ancestor A B - then - ... A is an ancestor of B ... - fi +.... +if git merge-base --is-ancestor A B +then + ... A is an ancestor of B ... +fi +.... instead. Discussion on fork-point mode ----------------------------- -After working on the `topic` branch created with `git checkout -b +After working on the `topic` branch created with `git switch -c topic origin/master`, the history of remote-tracking branch `origin/master` may have been rewound and rebuilt, leading to a history of this shape: - o---B2 - / - ---o---o---B1--o---o---o---B (origin/master) - \ - B0 - \ - D0---D1---D (topic) +.... + o---B2 + / +---o---o---B1--o---o---o---B (origin/master) + \ + B0 + \ + D0---D1---D (topic) +.... where `origin/master` used to point at commits B0, B1, B2 and now it points at B, and your `topic` branch was started on top of it back @@ -193,13 +207,15 @@ will find B0, and will replay D0, D1 and D on top of B to create a new history of this shape: - o---B2 - / - ---o---o---B1--o---o---o---B (origin/master) - \ \ - B0 D0'--D1'--D' (topic - updated) - \ - D0---D1---D (topic - old) +.... + o---B2 + / +---o---o---B1--o---o---o---B (origin/master) + \ \ + B0 D0'--D1'--D' (topic - updated) + \ + D0---D1---D (topic - old) +.... A caveat is that older reflog entries in your repository may be expired by `git gc`. If B0 no longer appears in the reflog of the diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.txt index 02676fb391..2ab84a91e5 100644 --- a/Documentation/git-merge-index.txt +++ b/Documentation/git-merge-index.txt @@ -54,20 +54,24 @@ original is first. But the argument order to the 3-way merge program Examples: - torvalds@ppc970:~/merge-test> git merge-index cat MM - This is MM from the original tree. # original - This is modified MM in the branch A. # merge1 - This is modified MM in the branch B. # merge2 - This is modified MM in the branch B. # current contents +---- +torvalds@ppc970:~/merge-test> git merge-index cat MM +This is MM from the original tree. # original +This is modified MM in the branch A. # merge1 +This is modified MM in the branch B. # merge2 +This is modified MM in the branch B. # current contents +---- or - torvalds@ppc970:~/merge-test> git merge-index cat AA MM - cat: : No such file or directory - This is added AA in the branch A. - This is added AA in the branch B. - This is added AA in the branch B. - fatal: merge program failed +---- +torvalds@ppc970:~/merge-test> git merge-index cat AA MM +cat: : No such file or directory +This is added AA in the branch A. +This is added AA in the branch B. +This is added AA in the branch B. +fatal: merge program failed +---- where the latter example shows how 'git merge-index' will stop trying to merge once anything has returned an error (i.e., `cat` returned an error diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 6294dbc09d..e4f3352eb5 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -10,11 +10,10 @@ SYNOPSIS -------- [verse] 'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] - [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] + [--no-verify] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [--[no-]allow-unrelated-histories] [--[no-]rerere-autoupdate] [-m <msg>] [-F <file>] [<commit>...] -'git merge' --abort -'git merge' --continue +'git merge' (--continue | --abort | --quit) DESCRIPTION ----------- @@ -62,6 +61,8 @@ merge has resulted in conflicts. OPTIONS ------- +:git-merge: 1 + include::merge-options.txt[] -m <msg>:: @@ -88,9 +89,15 @@ will be appended to the specified message. Allow the rerere mechanism to update the index with the result of auto-conflict resolution if possible. +--overwrite-ignore:: +--no-overwrite-ignore:: + Silently overwrite ignored files from the merge result. This + is the default behavior. Use `--no-overwrite-ignore` to abort. + --abort:: Abort the current conflict resolution process, and - try to reconstruct the pre-merge state. + try to reconstruct the pre-merge state. If an autostash entry is + present, apply it to the worktree. + If there were uncommitted worktree changes present when the merge started, 'git merge --abort' will in some cases be unable to @@ -98,7 +105,15 @@ reconstruct these changes. It is therefore recommended to always commit or stash your changes before running 'git merge'. + 'git merge --abort' is equivalent to 'git reset --merge' when -`MERGE_HEAD` is present. +`MERGE_HEAD` is present unless `MERGE_AUTOSTASH` is also present in +which case 'git merge --abort' applies the stash entry to the worktree +whereas 'git reset --merge' will save the stashed changes in the stash +list. + +--quit:: + Forget about the current merge in progress. Leave the index + and the working tree as-is. If `MERGE_AUTOSTASH` is present, the + stash entry will be saved to the stash list. --continue:: After a 'git merge' stops due to conflicts you can conclude the diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.txt index 4da9d24096..3e8f59ac0e 100644 --- a/Documentation/git-mergetool--lib.txt +++ b/Documentation/git-mergetool--lib.txt @@ -38,6 +38,10 @@ get_merge_tool_cmd:: get_merge_tool_path:: returns the custom path for a merge tool. +initialize_merge_tool:: + bring merge tool specific functions into scope so they can be used or + overridden. + run_merge_tool:: launches a merge tool given the tool name and a true/false flag to indicate whether a merge base is present. diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index 6b14702e78..e587c7763a 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -99,6 +99,10 @@ success of the resolution after the custom tool has exited. (see linkgit:git-config[1]). To cancel `diff.orderFile`, use `-O/dev/null`. +CONFIGURATION +------------- +include::config/mergetool.txt[] + TEMPORARY FILES --------------- `git mergetool` creates `*.orig` backup files while resolving merges. diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.txt index fa6a756123..466a697519 100644 --- a/Documentation/git-mktag.txt +++ b/Documentation/git-mktag.txt @@ -3,7 +3,7 @@ git-mktag(1) NAME ---- -git-mktag - Creates a tag object +git-mktag - Creates a tag object with extra validation SYNOPSIS @@ -13,23 +13,50 @@ SYNOPSIS DESCRIPTION ----------- -Reads a tag contents on standard input and creates a tag object -that can also be used to sign other objects. -The output is the new tag's <object> identifier. +Reads a tag contents on standard input and creates a tag object. The +output is the new tag's <object> identifier. + +This command is mostly equivalent to linkgit:git-hash-object[1] +invoked with `-t tag -w --stdin`. I.e. both of these will create and +write a tag found in `my-tag`: + + git mktag <my-tag + git hash-object -t tag -w --stdin <my-tag + +The difference is that mktag will die before writing the tag if the +tag doesn't pass a linkgit:git-fsck[1] check. + +The "fsck" check done mktag is stricter than what linkgit:git-fsck[1] +would run by default in that all `fsck.<msg-id>` messages are promoted +from warnings to errors (so e.g. a missing "tagger" line is an error). + +Extra headers in the object are also an error under mktag, but ignored +by linkgit:git-fsck[1]. This extra check can be turned off by setting +the appropriate `fsck.<msg-id>` varible: + + git -c fsck.extraHeaderEntry=ignore mktag <my-tag-with-headers + +OPTIONS +------- + +--strict:: + By default mktag turns on the equivalent of + linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to + disable it. Tag Format ---------- A tag signature file, to be fed to this command's standard input, has a very simple fixed format: four lines of - object <sha1> + object <hash> type <typename> tag <tagname> tagger <tagger> followed by some 'optional' free-form message (some tags created -by older Git may not have `tagger` line). The message, when +by older Git may not have `tagger` line). The message, when it exists, is separated by a blank line from the header. The message part may contain a signature that Git itself doesn't care about, but that can be verified with gpg. diff --git a/Documentation/git-multi-pack-index.txt b/Documentation/git-multi-pack-index.txt index f7778a2c85..ffd601bc17 100644 --- a/Documentation/git-multi-pack-index.txt +++ b/Documentation/git-multi-pack-index.txt @@ -9,7 +9,8 @@ git-multi-pack-index - Write and verify multi-pack-indexes SYNOPSIS -------- [verse] -'git multi-pack-index' [--object-dir=<dir>] <verb> +'git multi-pack-index' [--object-dir=<dir>] [--[no-]progress] + [--preferred-pack=<pack>] <subcommand> DESCRIPTION ----------- @@ -23,13 +24,52 @@ OPTIONS `<dir>/packs/multi-pack-index` for the current MIDX file, and `<dir>/packs` for the pack-files to index. +--[no-]progress:: + Turn progress on/off explicitly. If neither is specified, progress is + shown if standard error is connected to a terminal. + +The following subcommands are available: + write:: - When given as the verb, write a new MIDX file to - `<dir>/packs/multi-pack-index`. + Write a new MIDX file. The following options are available for + the `write` sub-command: ++ +-- + --preferred-pack=<pack>:: + Optionally specify the tie-breaking pack used when + multiple packs contain the same object. If not given, + ties are broken in favor of the pack with the lowest + mtime. +-- verify:: - When given as the verb, verify the contents of the MIDX file - at `<dir>/packs/multi-pack-index`. + Verify the contents of the MIDX file. + +expire:: + Delete the pack-files that are tracked by the MIDX file, but + have no objects referenced by the MIDX. Rewrite the MIDX file + afterward to remove all references to these pack-files. + +repack:: + Create a new pack-file containing objects in small pack-files + referenced by the multi-pack-index. If the size given by the + `--batch-size=<size>` argument is zero, then create a pack + containing all objects referenced by the multi-pack-index. For + a non-zero batch size, Select the pack-files by examining packs + from oldest-to-newest, computing the "expected size" by counting + the number of objects in the pack referenced by the + multi-pack-index, then divide by the total number of objects in + the pack and multiply by the pack size. We select packs with + expected size below the batch size until the set of packs have + total expected size at least the batch size, or all pack-files + are considered. If only one pack-file is selected, then do + nothing. If a new pack-file is created, rewrite the + multi-pack-index to reference the new pack-file. A later run of + 'git multi-pack-index expire' will delete the pack-files that + were part of this batch. ++ +If `repack.packKeptObjects` is `false`, then any pack-files with an +associated `.keep` file will not be selected for the batch to repack. EXAMPLES diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index f56a5a9197..0a4200674c 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -10,7 +10,7 @@ SYNOPSIS [verse] 'git notes' [list [<object>]] 'git notes' add [-f] [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>] -'git notes' copy [-f] ( --stdin | <from-object> <to-object> ) +'git notes' copy [-f] ( --stdin | <from-object> [<to-object>] ) 'git notes' append [--allow-empty] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>] 'git notes' edit [--allow-empty] [<object>] 'git notes' show [<object>] @@ -68,8 +68,8 @@ add:: subcommand). copy:: - Copy the notes for the first object onto the second object. - Abort if the second object already has notes, or if the first + Copy the notes for the first object onto the second object (defaults to + HEAD). Abort if the second object already has notes, or if the first object has none (use -f to overwrite existing notes to the second object). This subcommand is equivalent to: `git notes add [-f] -C $(git notes list <from-object>) <to-object>` @@ -223,7 +223,7 @@ are taken from notes refs. A notes ref is usually a branch which contains "files" whose paths are the object names for the objects they describe, with some directory separators included for performance reasons footnote:[Permitted pathnames have the form -'ab'`/`'cd'`/`'ef'`/`'...'`/`'abcdef...': a sequence of directory +'bf'`/`'fe'`/`'30'`/`'...'`/`'680d5a...': a sequence of directory names of two hexadecimal digits each followed by a filename with the rest of the object ID.]. diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.txt index 3494a1db3e..38e5257b2a 100644 --- a/Documentation/git-p4.txt +++ b/Documentation/git-p4.txt @@ -374,14 +374,55 @@ These options can be used to modify 'git p4 submit' behavior. been submitted. Implies --disable-rebase. Can also be set with git-p4.disableP4Sync. Sync with origin/master still goes ahead if possible. -Hook for submit -~~~~~~~~~~~~~~~ +Hooks for submit +---------------- + +p4-pre-submit +~~~~~~~~~~~~~ + The `p4-pre-submit` hook is executed if it exists and is executable. The hook takes no parameters and nothing from standard input. Exiting with non-zero status from this script prevents `git-p4 submit` from launching. +It can be bypassed with the `--no-verify` command line option. One usage scenario is to run unit tests in the hook. +p4-prepare-changelist +~~~~~~~~~~~~~~~~~~~~~ + +The `p4-prepare-changelist` hook is executed right after preparing +the default changelist message and before the editor is started. +It takes one parameter, the name of the file that contains the +changelist text. Exiting with a non-zero status from the script +will abort the process. + +The purpose of the hook is to edit the message file in place, +and it is not suppressed by the `--no-verify` option. This hook +is called even if `--prepare-p4-only` is set. + +p4-changelist +~~~~~~~~~~~~~ + +The `p4-changelist` hook is executed after the changelist +message has been edited by the user. It can be bypassed with the +`--no-verify` option. It takes a single parameter, the name +of the file that holds the proposed changelist text. Exiting +with a non-zero status causes the command to abort. + +The hook is allowed to edit the changelist file and can be used +to normalize the text into some project standard format. It can +also be used to refuse the Submit after inspect the message file. + +p4-post-changelist +~~~~~~~~~~~~~~~~~~ + +The `p4-post-changelist` hook is invoked after the submit has +successfully occurred in P4. It takes no parameters and is meant +primarily for notification and cannot affect the outcome of the +git p4 submit action. + + + Rebase options ~~~~~~~~~~~~~~ These options can be used to modify 'git p4 rebase' behavior. @@ -721,3 +762,7 @@ IMPLEMENTATION DETAILS message indicating the p4 depot location and change number. This line is used by later 'git p4 sync' operations to know which p4 changes are new. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index e45f3e680d..dbfd1f9017 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -14,7 +14,7 @@ SYNOPSIS [--local] [--incremental] [--window=<n>] [--depth=<n>] [--revs [--unpacked | --all]] [--keep-pack=<pack-name>] [--stdout [--filter=<filter-spec>] | base-name] - [--shallow] [--keep-true-parents] [--sparse] < object-list + [--shallow] [--keep-true-parents] [--[no-]sparse] < object-list DESCRIPTION @@ -85,6 +85,16 @@ base-name:: reference was included in the resulting packfile. This can be useful to send new tags to native Git clients. +--stdin-packs:: + Read the basenames of packfiles (e.g., `pack-1234abcd.pack`) + from the standard input, instead of object names or revision + arguments. The resulting pack contains all objects listed in the + included packs (those not beginning with `^`), excluding any + objects listed in the excluded packs (beginning with `^`). ++ +Incompatible with `--revs`, or options that imply `--revs` (such as +`--all`), with the exception of `--unpacked`, which is compatible. + --window=<n>:: --depth=<n>:: These two options affect how the objects contained in @@ -118,10 +128,10 @@ depth is 4095. into multiple independent packfiles, each not larger than the given size. The size can be suffixed with "k", "m", or "g". The minimum size allowed is limited to 1 MiB. - This option - prevents the creation of a bitmap index. The default is unlimited, unless the config variable - `pack.packSizeLimit` is set. + `pack.packSizeLimit` is set. Note that this option may result in + a larger and slower repository; see the discussion in + `pack.packSizeLimit`. --honor-pack-keep:: This flag causes an object already in a local pack that @@ -131,7 +141,7 @@ depth is 4095. --keep-pack=<pack-name>:: This flag causes an object already in the given pack to be ignored, even if it would have otherwise been - packed. `<pack-name>` is the the pack file name without + packed. `<pack-name>` is the pack file name without leading directory (e.g. `pack-123.pack`). The option could be specified multiple times to keep multiple packs. @@ -196,14 +206,16 @@ depth is 4095. 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 +--[no-]sparse:: + Toggle 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. + certain types of direct renames. If this option is not included, + it defaults to the value of `pack.useSparse`, which is true unless + otherwise specified. --thin:: Create a "thin" pack by omitting the common objects between a @@ -268,15 +280,18 @@ So does `git bundle` (see linkgit:git-bundle[1]) when it creates a bundle. This option specifies how missing objects are handled. + The form '--missing=error' requests that pack-objects stop with an error if -a missing object is encountered. This is the default action. +a missing object is encountered. If the repository is a partial clone, an +attempt to fetch missing objects will be made before declaring them missing. +This is the default action. + The form '--missing=allow-any' will allow object traversal to continue -if a missing object is encountered. Missing objects will silently be -omitted from the results. +if a missing object is encountered. No fetch of a missing object will occur. +Missing objects will silently be omitted from the results. + The form '--missing=allow-promisor' is like 'allow-any', but will only allow object traversal to continue for EXPECTED promisor missing objects. -Unexpected missing object will raise an error. +No fetch of a missing object will occur. An unexpected missing object will +raise an error. --exclude-promisor-objects:: Omit objects that are known to be in the promisor remote. (This @@ -395,6 +410,17 @@ Note that we pick a single island for each regex to go into, using "last one wins" ordering (which allows repo-specific config to take precedence over user-wide config, and so forth). + +CONFIGURATION +------------- + +Various configuration variables affect packing, see +linkgit:git-config[1] (search for "pack" and "delta"). + +Notably, delta compression is not used on objects larger than the +`core.bigFileThreshold` configuration variable and on files with the +attribute `delta` set to false. + SEE ALSO -------- linkgit:git-rev-list[1] diff --git a/Documentation/git-parse-remote.txt b/Documentation/git-parse-remote.txt deleted file mode 100644 index a45ea1ece8..0000000000 --- a/Documentation/git-parse-remote.txt +++ /dev/null @@ -1,23 +0,0 @@ -git-parse-remote(1) -=================== - -NAME ----- -git-parse-remote - Routines to help parsing remote repository access parameters - - -SYNOPSIS --------- -[verse] -'. "$(git --exec-path)/git-parse-remote"' - -DESCRIPTION ------------ -This script is included in various scripts to supply -routines to parse files under $GIT_DIR/remotes/ and -$GIT_DIR/branches/ and configuration variables that are related -to fetching, pulling and pushing. - -GIT ---- -Part of the linkgit:git[1] suite diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index a5e9501a0a..aef757ec89 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -15,14 +15,17 @@ SYNOPSIS DESCRIPTION ----------- -Incorporates changes from a remote repository into the current -branch. In its default mode, `git pull` is shorthand for -`git fetch` followed by `git merge FETCH_HEAD`. - -More precisely, 'git pull' runs 'git fetch' with the given -parameters and calls 'git merge' to merge the retrieved branch -heads into the current branch. -With `--rebase`, it runs 'git rebase' instead of 'git merge'. +Incorporates changes from a remote repository into the current branch. +If the current branch is behind the remote, then by default it will +fast-forward the current branch to match the remote. If the current +branch and the remote have diverged, the user needs to specify how to +reconcile the divergent branches with `--rebase` or `--no-rebase` (or +the corresponding configuration option in `pull.rebase`). + +More precisely, `git pull` runs `git fetch` with the given parameters +and then depending on configuration options or command line flags, +will call either `git rebase` or `git merge` to reconcile diverging +branches. <repository> should be the name of a remote repository as passed to linkgit:git-fetch[1]. <refspec> can name an @@ -85,8 +88,9 @@ OPTIONS Pass --verbose to git-fetch and git-merge. --[no-]recurse-submodules[=yes|on-demand|no]:: - This option controls if new commits of all populated submodules should - be fetched and updated, too (see linkgit:git-config[1] and + This option controls if new commits of populated submodules should + be fetched, and if the working trees of active submodules should be + updated, too (see linkgit:git-fetch[1], linkgit:git-config[1] and linkgit:gitmodules[5]). + If the checkout is done via rebase, local submodule commits are rebased as well. @@ -116,7 +120,7 @@ When set to `preserve` (deprecated in favor of `merges`), rebase with the `--preserve-merges` option passed to `git rebase` so that locally created merge commits will not be flattened. + -When false, merge the current branch into the upstream branch. +When false, merge the upstream branch into the current branch. + When `interactive`, enable the interactive mode of rebase. + @@ -131,16 +135,7 @@ published that history already. Do *not* use this option unless you have read linkgit:git-rebase[1] carefully. --no-rebase:: - Override earlier --rebase. - ---autostash:: ---no-autostash:: - Before starting rebase, stash local modifications away (see - linkgit:git-stash[1]) if needed, and apply the stash entry when - done. `--no-autostash` is useful to override the `rebase.autoStash` - configuration variable (see linkgit:git-config[1]). -+ -This option is only valid when "--rebase" is used. + This is shorthand for --rebase=false. Options related to fetching ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -229,9 +224,9 @@ branch.<name>.merge options; see linkgit:git-config[1] for details. $ git pull origin next ------------------------------------------------ + -This leaves a copy of `next` temporarily in FETCH_HEAD, but -does not update any remote-tracking branches. Using remote-tracking -branches, the same can be done by invoking fetch and merge: +This leaves a copy of `next` temporarily in FETCH_HEAD, and +updates the remote-tracking branch `origin/next`. +The same can be done by invoking fetch and merge: + ------------------------------------------------ $ git fetch origin @@ -249,7 +244,7 @@ BUGS ---- Using --recurse-submodules can only fetch new commits in already checked out submodules right now. When e.g. upstream added a new submodule in the -just fetched commits of the superproject the submodule itself can not be +just fetched commits of the superproject the submodule itself cannot be fetched, making it impossible to check out that submodule later without having to do a fetch again. This is expected to be fixed in a future Git version. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 6a8a0d958b..2f25aa3a29 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -13,7 +13,7 @@ SYNOPSIS [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose] [-u | --set-upstream] [-o <string> | --push-option=<string>] [--[no-]signed|--signed=(true|false|if-asked)] - [--force-with-lease[=<refname>[:<expect>]]] + [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]] [--no-verify] [<repository> [<refspec>...]] DESCRIPTION @@ -75,7 +75,7 @@ without any `<refspec>` on the command line. Otherwise, missing + 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> +belongs based on the type of <src> being pushed and whether <dst> is ambiguous. + -- @@ -244,8 +244,8 @@ Imagine that you have to rebase what you have already published. You will have to bypass the "must fast-forward" rule in order to replace the history you originally published with the rebased history. If somebody else built on top of your original history while you are -rebasing, the tip of the branch at the remote may advance with her -commit, and blindly pushing with `--force` will lose her work. +rebasing, the tip of the branch at the remote may advance with their +commit, and blindly pushing with `--force` will lose their work. + This option allows you to say that you expect the history you are updating is what you rebased and want to replace. If the remote ref @@ -320,6 +320,14 @@ seen and are willing to overwrite, then rewrite history, and finally force push changes to `master` if the remote version is still at `base`, regardless of what your local `remotes/origin/master` has been updated to in the background. ++ +Alternatively, specifying `--force-if-includes` as an ancillary option +along with `--force-with-lease[=<refname>]` (i.e., without saying what +exact commit the ref on the remote side must be pointing at, or which +refs on the remote side are being protected) at the time of "push" will +verify if updates from the remote-tracking refs that may have been +implicitly updated in the background are integrated locally before +allowing a forced update. -f:: --force:: @@ -341,6 +349,22 @@ one branch, use a `+` in front of the refspec to push (e.g `git push origin +master` to force a push to the `master` branch). See the `<refspec>...` section above for details. +--[no-]force-if-includes:: + Force an update only if the tip of the remote-tracking ref + has been integrated locally. ++ +This option enables a check that verifies if the tip of the +remote-tracking ref is reachable from one of the "reflog" entries of +the local branch based in it for a rewrite. The check ensures that any +updates from the remote have been incorporated locally by rejecting the +forced update if that is not the case. ++ +If the option is passed without specifying `--force-with-lease`, or +specified along with `--force-with-lease=<refname>:<expect>`, it is +a "no-op". ++ +Specifying `--no-force-if-includes` disables this behavior. + --repo=<repository>:: This option is equivalent to the <repository> argument. If both are specified, the command-line argument takes precedence. @@ -576,7 +600,7 @@ EXAMPLES `git push origin`:: Without additional configuration, pushes the current branch to - the configured upstream (`remote.origin.merge` configuration + the configured upstream (`branch.<name>.merge` configuration variable) if it has the same name as the current branch, and errors out without pushing otherwise. + diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.txt index 8a6ea2c6c5..fe350d7f40 100644 --- a/Documentation/git-range-diff.txt +++ b/Documentation/git-range-diff.txt @@ -10,6 +10,7 @@ SYNOPSIS [verse] 'git range-diff' [--color=[<when>]] [--no-color] [<diff-options>] [--no-dual-color] [--creation-factor=<factor>] + [--left-only | --right-only] ( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> ) DESCRIPTION @@ -28,6 +29,17 @@ Finally, the list of matching commits is shown in the order of the second commit range, with unmatched commits being inserted just after all of their ancestors have been shown. +There are three ways to specify the commit ranges: + +- `<range1> <range2>`: Either commit range can be of the form + `<base>..<rev>`, `<rev>^!` or `<rev>^-<n>`. See `SPECIFYING RANGES` + in linkgit:gitrevisions[7] for more details. + +- `<rev1>...<rev2>`. This is equivalent to + `<rev2>..<rev1> <rev1>..<rev2>`. + +- `<base> <rev1> <rev2>`: This is equivalent to `<base>..<rev1> + <base>..<rev2>`. OPTIONS ------- @@ -57,6 +69,18 @@ to revert to color all lines according to the outer diff markers See the ``Algorithm`` section below for an explanation why this is needed. +--left-only:: + Suppress commits that are missing from the first specified range + (or the "left range" when using the `<rev1>...<rev2>` format). + +--right-only:: + Suppress commits that are missing from the second specified range + (or the "right range" when using the `<rev1>...<rev2>` format). + +--[no-]notes[=<ref>]:: + This flag is passed to the `git log` program + (see linkgit:git-log[1]) that generates the patches. + <range1> <range2>:: Compare the commits specified by the two ranges, where `<range1>` is considered an older version of `<range2>`. @@ -75,7 +99,7 @@ to revert to color all lines according to the outer diff markers linkgit:git-diff[1]), most notably the `--color=[<when>]` and `--no-color` options. These options are used when generating the "diff between patches", i.e. to compare the author, commit message and diff of -corresponding old/new commits. There is currently no means to tweak the +corresponding old/new commits. There is currently no means to tweak most of the diff options passed to `git log` when generating those patches. OUTPUT STABILITY @@ -242,7 +266,7 @@ corresponding. The overall time needed to compute this algorithm is the time needed to compute n+m commit diffs and then n*m diffs of patches, plus the time -needed to compute the least-cost assigment between n and m diffs. Git +needed to compute the least-cost assignment between n and m diffs. Git uses an implementation of the Jonker-Volgenant algorithm to solve the assignment problem, which has cubic runtime complexity. The matching found in this case will look like this: diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index d271842608..5fa8bab64c 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -116,9 +116,9 @@ OPTIONS located in. --[no-]recurse-submodules:: - Using --recurse-submodules will update the content of all initialized + Using --recurse-submodules will update the content of all active submodules according to the commit recorded in the superproject by - calling read-tree recursively, also setting the submodules HEAD to be + calling read-tree recursively, also setting the submodules' HEAD to be detached at that commit. --no-sparse-checkout:: @@ -436,7 +436,7 @@ support. SEE ALSO -------- linkgit:git-write-tree[1]; linkgit:git-ls-files[1]; -linkgit:gitignore[5] +linkgit:gitignore[5]; linkgit:git-sparse-checkout[1]; GIT --- diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 5e4e927647..3f1030df70 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -8,16 +8,16 @@ git-rebase - Reapply commits on top of another base tip SYNOPSIS -------- [verse] -'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] - [<upstream> [<branch>]] +'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] + [--onto <newbase> | --keep-base] [<upstream> [<branch>]] 'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>] --root [<branch>] -'git rebase' --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch +'git rebase' (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch) DESCRIPTION ----------- If <branch> is specified, 'git rebase' will perform an automatic -`git checkout <branch>` before doing anything else. Otherwise +`git switch <branch>` before doing anything else. Otherwise it remains on the current branch. If <upstream> is not specified, the upstream configured in @@ -200,11 +200,6 @@ Alternatively, you can undo the 'git rebase' with git rebase --abort -CONFIGURATION -------------- - -include::config/rebase.txt[] - OPTIONS ------- --onto <newbase>:: @@ -217,6 +212,24 @@ As a special case, you may use "A\...B" as a shortcut for the merge base of A and B if there is exactly one merge base. You can leave out at most one of A and B, in which case it defaults to HEAD. +--keep-base:: + Set the starting point at which to create the new commits to the + merge base of <upstream> <branch>. Running + 'git rebase --keep-base <upstream> <branch>' is equivalent to + running 'git rebase --onto <upstream>... <upstream>'. ++ +This option is useful in the case where one is developing a feature on +top of an upstream branch. While the feature is being worked on, the +upstream branch may advance and it may not be the best idea to keep +rebasing on top of the upstream but to keep the base commit as-is. ++ +Although both this option and --fork-point find the merge base between +<upstream> and <branch>, this option uses the merge base as the _starting +point_ on which new commits will be created, whereas --fork-point uses +the merge base to determine the _set of commits_ which will be rebased. ++ +See also INCOMPATIBLE OPTIONS below. + <upstream>:: Upstream branch to compare against. May be any valid commit, not just an existing branch name. Defaults to the configured @@ -238,18 +251,79 @@ leave out at most one of A and B, in which case it defaults to HEAD. --quit:: Abort the rebase operation but HEAD is not reset back to the original branch. The index and working tree are also left - unchanged as a result. + unchanged as a result. If a temporary stash entry was created + using --autostash, it will be saved to the stash list. + +--apply:: + Use applying strategies to rebase (calling `git-am` + internally). This option may become a no-op in the future + once the merge backend handles everything the apply one does. ++ +See also INCOMPATIBLE OPTIONS below. + +--empty={drop,keep,ask}:: + How to handle commits that are not empty to start and are not + clean cherry-picks of any upstream commit, but which become + empty after rebasing (because they contain a subset of already + upstream changes). With drop (the default), commits that + become empty are dropped. With keep, such commits are kept. + With ask (implied by --interactive), the rebase will halt when + an empty commit is applied allowing you to choose whether to + drop it, edit files more, or just commit the empty changes. + Other options, like --exec, will use the default of drop unless + -i/--interactive is explicitly specified. ++ +Note that commits which start empty are kept (unless --no-keep-empty +is specified), and commits which are clean cherry-picks (as determined +by `git log --cherry-mark ...`) are detected and dropped as a +preliminary step (unless --reapply-cherry-picks is passed). ++ +See also INCOMPATIBLE OPTIONS below. +--no-keep-empty:: --keep-empty:: - Keep the commits that do not change anything from its - parents in the result. + Do not keep commits that start empty before the rebase + (i.e. that do not change anything from its parent) in the + result. The default is to keep commits which start empty, + since creating such commits requires passing the --allow-empty + override flag to `git commit`, signifying that a user is very + intentionally creating such a commit and thus wants to keep + it. ++ +Usage of this flag will probably be rare, since you can get rid of +commits that start empty by just firing up an interactive rebase and +removing the lines corresponding to the commits you don't want. This +flag exists as a convenient shortcut, such as for cases where external +tools generate many empty commits and you want them all removed. ++ +For commits which do not start empty but become empty after rebasing, +see the --empty flag. ++ +See also INCOMPATIBLE OPTIONS below. + +--reapply-cherry-picks:: +--no-reapply-cherry-picks:: + Reapply all clean cherry-picks of any upstream commit instead + of preemptively dropping them. (If these commits then become + empty after rebasing, because they contain a subset of already + upstream changes, the behavior towards them is controlled by + the `--empty` flag.) ++ +By default (or if `--no-reapply-cherry-picks` is given), these commits +will be automatically dropped. Because this necessitates reading all +upstream commits, this can be expensive in repos with a large number +of upstream commits that need to be read. ++ +`--reapply-cherry-picks` allows rebase to forgo reading all upstream +commits, potentially improving performance. + See also INCOMPATIBLE OPTIONS below. --allow-empty-message:: - By default, rebasing commits with an empty message will fail. - This option overrides that behavior, allowing commits with empty - messages to be rebased. + No-op. Rebasing commits with an empty message used to fail + and this option would override that behavior, allowing commits + with empty messages to be rebased. Now commits with an empty + message do not cause rebasing to halt. + See also INCOMPATIBLE OPTIONS below. @@ -266,9 +340,7 @@ See also INCOMPATIBLE OPTIONS below. -m:: --merge:: - Use merging strategies to rebase. When the recursive (default) merge - strategy is used, this allows rebase to be aware of renames on the - upstream side. + Using merging strategies to rebase (default). + Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream> branch. Because of this, when a merge @@ -280,9 +352,8 @@ See also INCOMPATIBLE OPTIONS below. -s <strategy>:: --strategy=<strategy>:: - Use the given merge strategy. - If there is no `-s` option 'git merge-recursive' is used - instead. This implies --merge. + Use the given merge strategy, instead of the default `ort`. + This implies `--merge`. + Because 'git rebase' replays each commit from the working branch on top of the <upstream> branch using the given strategy, using @@ -295,7 +366,7 @@ See also INCOMPATIBLE OPTIONS below. --strategy-option=<strategy-option>:: Pass the <strategy-option> through to the merge strategy. This implies `--merge` and, if no strategy has been - specified, `-s recursive`. Note the reversal of 'ours' and + specified, `-s ort`. Note the reversal of 'ours' and 'theirs' as noted above for the `-m` option. + See also INCOMPATIBLE OPTIONS below. @@ -307,9 +378,12 @@ See also INCOMPATIBLE OPTIONS below. -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand both `commit.gpgSign` configuration variable, and + earlier `--gpg-sign`. -q:: --quiet:: @@ -338,7 +412,7 @@ See also INCOMPATIBLE OPTIONS below. Ensure at least <n> lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is - ever ignored. + ever ignored. Implies --apply. + See also INCOMPATIBLE OPTIONS below. @@ -367,25 +441,53 @@ When --fork-point is active, 'fork_point' will be used instead of <branch>` command (see linkgit:git-merge-base[1]). If 'fork_point' ends up being empty, the <upstream> will be used as a fallback. + -If either <upstream> or --root is given on the command line, then the -default is `--no-fork-point`, otherwise the default is `--fork-point`. +If <upstream> is given on the command line, then the default is +`--no-fork-point`, otherwise the default is `--fork-point`. ++ +If your branch was based on <upstream> but <upstream> was rewound and +your branch contains commits which were dropped, this option can be used +with `--keep-base` in order to drop those commits from your branch. ++ +See also INCOMPATIBLE OPTIONS below. --ignore-whitespace:: + Ignore whitespace differences when trying to reconcile +differences. Currently, each backend implements an approximation of +this behavior: ++ +apply backend: When applying a patch, ignore changes in whitespace in +context lines. Unfortunately, this means that if the "old" lines being +replaced by the patch differ only in whitespace from the existing +file, you will get a merge conflict instead of a successful patch +application. ++ +merge backend: Treat lines with only whitespace changes as unchanged +when merging. Unfortunately, this means that any patch hunks that were +intended to modify whitespace and nothing else will be dropped, even +if the other side had no changes that conflicted. + --whitespace=<option>:: - These flag are passed to the 'git apply' program + This flag is passed to the 'git apply' program (see linkgit:git-apply[1]) that applies the patch. + Implies --apply. + See also INCOMPATIBLE OPTIONS below. --committer-date-is-author-date:: + Instead of using the current time as the committer date, use + the author date of the commit being rebased as the committer + date. This option implies `--force-rebase`. + --ignore-date:: - These flags are passed to 'git am' to easily change the dates - of the rebased commits (see linkgit:git-am[1]). +--reset-author-date:: + Instead of using the author date of the original commit, use + the current time as the author date of the rebased commit. This + option implies `--force-rebase`. + See also INCOMPATIBLE OPTIONS below. --signoff:: - Add a Signed-off-by: trailer to all the rebased commits. Note + Add a `Signed-off-by` trailer to all the rebased commits. Note that if `--interactive` is given then only commits marked to be picked, edited or reworded will have the trailer added. + @@ -421,11 +523,11 @@ the `rebase-cousins` mode is turned on, such commits are instead rebased onto `<upstream>` (or `<onto>`, if specified). + The `--rebase-merges` mode is similar in spirit to the deprecated -`--preserve-merges`, but in contrast to that option works well in interactive -rebases: commits can be reordered, inserted and dropped at will. +`--preserve-merges` but works with interactive rebases, +where commits can be reordered, inserted and dropped at will. + It is currently only possible to recreate the merge commits using the -`recursive` merge strategy; Different merge strategies can be used only via +`ort` merge strategy; different merge strategies can be used only via explicit `exec git merge -s <strategy> [...]` commands. + See also REBASING MERGES and INCOMPATIBLE OPTIONS below. @@ -482,16 +584,17 @@ See also INCOMPATIBLE OPTIONS below. --autosquash:: --no-autosquash:: - When the commit log message begins with "squash! ..." (or - "fixup! ..."), and there is already a commit in the todo list that - matches the same `...`, automatically modify the todo list of rebase - -i so that the commit marked for squashing comes right after the - commit to be modified, and change the action of the moved commit - from `pick` to `squash` (or `fixup`). A commit matches the `...` if - the commit subject matches, or if the `...` refers to the commit's - hash. As a fall-back, partial matches of the commit subject work, - too. The recommended way to create fixup/squash commits is by using - the `--fixup`/`--squash` options of linkgit:git-commit[1]. + When the commit log message begins with "squash! ..." or "fixup! ..." + or "amend! ...", and there is already a commit in the todo list that + matches the same `...`, automatically modify the todo list of + `rebase -i`, so that the commit marked for squashing comes right after + the commit to be modified, and change the action of the moved commit + from `pick` to `squash` or `fixup` or `fixup -C` respectively. A commit + matches the `...` if the commit subject matches, or if the `...` refers + to the commit's hash. As a fall-back, partial matches of the commit + subject work, too. The recommended way to create fixup/amend/squash + commits is by using the `--fixup`, `--fixup=amend:` or `--fixup=reword:` + and `--squash` options respectively of linkgit:git-commit[1]. + If the `--autosquash` option is enabled by default using the configuration variable `rebase.autoSquash`, this option can be @@ -511,16 +614,22 @@ See also INCOMPATIBLE OPTIONS below. --no-reschedule-failed-exec:: Automatically reschedule `exec` commands that failed. This only makes sense in interactive mode (or when an `--exec` option was provided). ++ +Even though this option applies once a rebase is started, it's set for +the whole rebase at the start based on either the +`rebase.rescheduleFailedExec` configuration (see linkgit:git-config[1] +or "CONFIGURATION" below) or whether this option is +provided. Otherwise an explicit `--no-reschedule-failed-exec` at the +start would be overridden by the presence of +`rebase.rescheduleFailedExec=true` configuration. INCOMPATIBLE OPTIONS -------------------- The following options: - * --committer-date-is-author-date - * --ignore-date + * --apply * --whitespace - * --ignore-whitespace * -C are incompatible with the following options: @@ -534,7 +643,9 @@ are incompatible with the following options: * --preserve-merges * --interactive * --exec - * --keep-empty + * --no-keep-empty + * --empty= + * --reapply-cherry-picks * --edit-todo * --root when used in combination with --onto @@ -543,33 +654,152 @@ In addition, the following pairs of options are incompatible: * --preserve-merges and --interactive * --preserve-merges and --signoff * --preserve-merges and --rebase-merges - * --rebase-merges and --strategy - * --rebase-merges and --strategy-option + * --preserve-merges and --empty= + * --preserve-merges and --ignore-whitespace + * --preserve-merges and --committer-date-is-author-date + * --preserve-merges and --ignore-date + * --keep-base and --onto + * --keep-base and --root + * --fork-point and --root BEHAVIORAL DIFFERENCES ----------------------- -There are some subtle differences how the backends behave. +git rebase has two primary backends: apply and merge. (The apply +backend used to be known as the 'am' backend, but the name led to +confusion as it looks like a verb instead of a noun. Also, the merge +backend used to be known as the interactive backend, but it is now +used for non-interactive cases as well. Both were renamed based on +lower-level functionality that underpinned each.) There are some +subtle differences in how these two backends behave: Empty commits ~~~~~~~~~~~~~ -The am backend drops any "empty" commits, regardless of whether the -commit started empty (had no changes relative to its parent to -start with) or ended empty (all changes were already applied -upstream in other commits). +The apply backend unfortunately drops intentionally empty commits, i.e. +commits that started empty, though these are rare in practice. It +also drops commits that become empty and has no option for controlling +this behavior. -The interactive backend drops commits by default that -started empty and halts if it hits a commit that ended up empty. -The `--keep-empty` option exists for the interactive backend to allow -it to keep commits that started empty. +The merge backend keeps intentionally empty commits by default (though +with -i they are marked as empty in the todo list editor, or they can +be dropped automatically with --no-keep-empty). + +Similar to the apply backend, by default the merge backend drops +commits that become empty unless -i/--interactive is specified (in +which case it stops and asks the user what to do). The merge backend +also has an --empty={drop,keep,ask} option for changing the behavior +of handling commits that become empty. Directory rename detection ~~~~~~~~~~~~~~~~~~~~~~~~~~ -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. +Due to the lack of accurate tree information (arising from +constructing fake ancestors with the limited information available in +patches), directory rename detection is disabled in the apply backend. +Disabled directory rename detection means that if one side of history +renames a directory and the other adds new files to the old directory, +then the new files will be left behind in the old directory without +any warning at the time of rebasing that you may want to move these +files into the new directory. + +Directory rename detection works with the merge backend to provide you +warnings in such cases. + +Context +~~~~~~~ + +The apply backend works by creating a sequence of patches (by calling +`format-patch` internally), and then applying the patches in sequence +(calling `am` internally). Patches are composed of multiple hunks, +each with line numbers, a context region, and the actual changes. The +line numbers have to be taken with some fuzz, since the other side +will likely have inserted or deleted lines earlier in the file. The +context region is meant to help find how to adjust the line numbers in +order to apply the changes to the right lines. However, if multiple +areas of the code have the same surrounding lines of context, the +wrong one can be picked. There are real-world cases where this has +caused commits to be reapplied incorrectly with no conflicts reported. +Setting diff.context to a larger value may prevent such types of +problems, but increases the chance of spurious conflicts (since it +will require more lines of matching context to apply). + +The merge backend works with a full copy of each relevant file, +insulating it from these types of problems. + +Labelling of conflicts markers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When there are content conflicts, the merge machinery tries to +annotate each side's conflict markers with the commits where the +content came from. Since the apply backend drops the original +information about the rebased commits and their parents (and instead +generates new fake commits based off limited information in the +generated patches), those commits cannot be identified; instead it has +to fall back to a commit summary. Also, when merge.conflictStyle is +set to diff3, the apply backend will use "constructed merge base" to +label the content from the merge base, and thus provide no information +about the merge base commit whatsoever. + +The merge backend works with the full commits on both sides of history +and thus has no such limitations. + +Hooks +~~~~~ + +The apply backend has not traditionally called the post-commit hook, +while the merge backend has. Both have called the post-checkout hook, +though the merge backend has squelched its output. Further, both +backends only call the post-checkout hook with the starting point +commit of the rebase, not the intermediate commits nor the final +commit. In each case, the calling of these hooks was by accident of +implementation rather than by design (both backends were originally +implemented as shell scripts and happened to invoke other commands +like 'git checkout' or 'git commit' that would call the hooks). Both +backends should have the same behavior, though it is not entirely +clear which, if any, is correct. We will likely make rebase stop +calling either of these hooks in the future. + +Interruptability +~~~~~~~~~~~~~~~~ + +The apply backend has safety problems with an ill-timed interrupt; if +the user presses Ctrl-C at the wrong time to try to abort the rebase, +the rebase can enter a state where it cannot be aborted with a +subsequent `git rebase --abort`. The merge backend does not appear to +suffer from the same shortcoming. (See +https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ for +details.) + +Commit Rewording +~~~~~~~~~~~~~~~~ + +When a conflict occurs while rebasing, rebase stops and asks the user +to resolve. Since the user may need to make notable changes while +resolving conflicts, after conflicts are resolved and the user has run +`git rebase --continue`, the rebase should open an editor and ask the +user to update the commit message. The merge backend does this, while +the apply backend blindly applies the original commit message. + +Miscellaneous differences +~~~~~~~~~~~~~~~~~~~~~~~~~ + +There are a few more behavioral differences that most folks would +probably consider inconsequential but which are mentioned for +completeness: + +* Reflog: The two backends will use different wording when describing + the changes made in the reflog, though both will make use of the + word "rebase". + +* Progress, informational, and error messages: The two backends + provide slightly different progress and informational messages. + Also, the apply backend writes error messages (such as "Your files + would be overwritten...") to stdout, while the merge backend writes + them to stderr. + +* State directories: The two backends keep their state in different + directories under .git/ include::merge-strategies.txt[] @@ -657,9 +887,17 @@ If you want to fold two or more commits into one, replace the command "pick" for the second and subsequent commits with "squash" or "fixup". If the commits had different authors, the folded commit will be attributed to the author of the first commit. The suggested commit -message for the folded commit is the concatenation of the commit -messages of the first commit and of those with the "squash" command, -but omits the commit messages of commits with the "fixup" command. +message for the folded commit is the concatenation of the first +commit's message with those identified by "squash" commands, omitting the +messages of commits identified by "fixup" commands, unless "fixup -c" +is used. In that case the suggested commit message is only the message +of the "fixup -c" commit, and an editor is opened allowing you to edit +the message. The contents (patch) of the "fixup -c" commit are still +incorporated into the folded commit. If there is more than one "fixup -c" +commit, the message from the final one is used. You can also use +"fixup -C" to get the same behavior as "fixup -c" except without opening +an editor. + 'git rebase' will stop when "pick" has been replaced with "edit" or when a command fails due to merge errors. When you are done editing @@ -832,7 +1070,8 @@ Hard case: The changes are not the same.:: This happens if the 'subsystem' rebase had conflicts, or used `--interactive` to omit, edit, squash, or fixup commits; or if the upstream used one of `commit --amend`, `reset`, or - `filter-branch`. + a full history rewriting command like + https://github.com/newren/git-filter-repo[`filter-repo`]. The easy case @@ -843,7 +1082,8 @@ Only works if the changes (patch IDs based on the diff contents) on 'subsystem' did. In that case, the fix is easy because 'git rebase' knows to skip -changes that are already present in the new upstream. So if you say +changes that are already present in the new upstream (unless +`--reapply-cherry-picks` is given). So if you say (assuming you're on 'topic') ------------ $ git rebase subsystem @@ -870,7 +1110,7 @@ NOTE: While an "easy case recovery" sometimes appears to be successful --interactive` will be **resurrected**! The idea is to manually tell 'git rebase' "where the old 'subsystem' -ended and your 'topic' began", that is, what the old merge-base +ended and your 'topic' began", that is, what the old merge base between them was. You will have to find a way to name the last commit of the old 'subsystem', for example: @@ -976,12 +1216,16 @@ successful merge so that the user can edit the message. If a `merge` command fails for any reason other than merge conflicts (i.e. when the merge operation did not even start), it is rescheduled immediately. -At this time, the `merge` command will *always* use the `recursive` -merge strategy for regular merges, and `octopus` for octopus merges, -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). +By default, the `merge` command will use the `ort` merge strategy for +regular merges, and `octopus` for octopus merges. One can specify a +default strategy for all merges using the `--strategy` argument when +invoking rebase, or can override specific merges in the interactive +list of commands by using an `exec` command to call `git merge` +explicitly with a `--strategy` argument. Note that when calling `git +merge` explicitly like this, you can make use of the fact that the +labels are worktree-local refs (the ref `refs/rewritten/onto` would +correspond to the label `onto`, for example) in order to refer to the +branches you want to merge. Note: the first command (`label onto`) labels the revision onto which the commits are rebased; The name `onto` is just a convention, as a nod @@ -1025,6 +1269,12 @@ merge tlsv1.3 merge cmake ------------ +CONFIGURATION +------------- + +include::config/rebase.txt[] +include::config/sequencer.txt[] + BUGS ---- The todo list presented by the deprecated `--preserve-merges --interactive` diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt index dedf97efbb..25702ed730 100644 --- a/Documentation/git-receive-pack.txt +++ b/Documentation/git-receive-pack.txt @@ -165,29 +165,31 @@ ref listing the commits pushed to the repository, and logs the push certificates of signed pushes with good signatures to a logger service: - #!/bin/sh - # mail out commit update information. - while read oval nval ref - do - if expr "$oval" : '0*$' >/dev/null - then - echo "Created a new ref, with the following commits:" - git rev-list --pretty "$nval" - else - echo "New commits:" - git rev-list --pretty "$nval" "^$oval" - fi | - mail -s "Changes to ref $ref" commit-list@mydomain - done - # log signed push certificate, if any - if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G +---- +#!/bin/sh +# mail out commit update information. +while read oval nval ref +do + if expr "$oval" : '0*$' >/dev/null then - ( - echo expected nonce is ${GIT_PUSH_NONCE} - git cat-file blob ${GIT_PUSH_CERT} - ) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain - fi - exit 0 + echo "Created a new ref, with the following commits:" + git rev-list --pretty "$nval" + else + echo "New commits:" + git rev-list --pretty "$nval" "^$oval" + fi | + mail -s "Changes to ref $ref" commit-list@mydomain +done +# log signed push certificate, if any +if test -n "${GIT_PUSH_CERT-}" && test ${GIT_PUSH_CERT_STATUS} = G +then + ( + echo expected nonce is ${GIT_PUSH_NONCE} + git cat-file blob ${GIT_PUSH_CERT} + ) | mail -s "push certificate from $GIT_PUSH_CERT_SIGNER" push-log@mydomain +fi +exit 0 +---- The exit code from this hook invocation is ignored, however a non-zero exit code will generate an error message. @@ -212,8 +214,10 @@ anyway. This hook can be used, for example, to run `git update-server-info` if the repository is packed and is served via a dumb transport. - #!/bin/sh - exec git update-server-info +---- +#!/bin/sh +exec git update-server-info +---- QUARANTINE ENVIRONMENT diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index 0cad37fb81..31c29c9b31 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git remote' [-v | --verbose] -'git remote add' [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url> +'git remote add' [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <url> 'git remote rename' <old> <new> 'git remote remove' <name> 'git remote set-head' <name> (-a | --auto | -d | --delete | <branch>) @@ -35,7 +35,7 @@ OPTIONS -v:: --verbose:: Be a little more verbose and show remote url after name. - NOTE: This must be placed between `remote` and `subcommand`. + NOTE: This must be placed between `remote` and subcommand. COMMANDS @@ -46,7 +46,7 @@ subcommands are available to perform operations on the remotes. 'add':: -Adds a remote named <name> for the repository at +Add a remote named <name> for the repository at <url>. The command `git fetch <name>` can then be used to create and update remote-tracking branches <name>/<branch>. + @@ -109,13 +109,13 @@ With `-d` or `--delete`, the symbolic ref `refs/remotes/<name>/HEAD` is deleted. + With `-a` or `--auto`, the remote is queried to determine its `HEAD`, then the symbolic-ref `refs/remotes/<name>/HEAD` is set to the same branch. e.g., if the remote -`HEAD` is pointed at `next`, "`git remote set-head origin -a`" will set +`HEAD` is pointed at `next`, `git remote set-head origin -a` will set the symbolic-ref `refs/remotes/origin/HEAD` to `refs/remotes/origin/next`. This will only work if `refs/remotes/origin/next` already exists; if not it must be fetched first. + -Use `<branch>` to set the symbolic-ref `refs/remotes/<name>/HEAD` explicitly. e.g., "git -remote set-head origin master" will set the symbolic-ref `refs/remotes/origin/HEAD` to +Use `<branch>` to set the symbolic-ref `refs/remotes/<name>/HEAD` explicitly. e.g., `git +remote set-head origin master` will set the symbolic-ref `refs/remotes/origin/HEAD` to `refs/remotes/origin/master`. This will only work if `refs/remotes/origin/master` already exists; if not it must be fetched first. + @@ -127,7 +127,7 @@ This can be used to track a subset of the available remote branches after the initial setup for a remote. + The named branches will be interpreted as if specified with the -`-t` option on the 'git remote add' command line. +`-t` option on the `git remote add` command line. + With `--add`, instead of replacing the list of currently tracked branches, adds to that list. @@ -181,16 +181,16 @@ fetch --prune <name>`, except that no new references will be fetched. See the PRUNING section of linkgit:git-fetch[1] for what it'll prune depending on various configuration. + -With `--dry-run` option, report what branches will be pruned, but do not +With `--dry-run` option, report what branches would be pruned, but do not actually prune them. 'update':: Fetch updates for remotes or remote groups in the repository as defined by -remotes.<group>. If neither group nor remote is specified on the command line, +`remotes.<group>`. If neither group nor remote is specified on the command line, the configuration parameter remotes.default will be used; if remotes.default is not defined, all remotes which do not have the -configuration parameter remote.<name>.skipDefaultUpdate set to true will +configuration parameter `remote.<name>.skipDefaultUpdate` set to true will be updated. (See linkgit:git-config[1]). + With `--prune` option, run pruning against all the remotes that are updated. @@ -203,6 +203,17 @@ The remote configuration is achieved using the `remote.origin.url` and `remote.origin.fetch` configuration variables. (See linkgit:git-config[1]). +EXIT STATUS +----------- + +On success, the exit status is `0`. + +When subcommands such as 'add', 'rename', and 'remove' can't find the +remote in question, the exit status is `2`. When the remote already +exists, the exit status is `3`. + +On any other error, the exit status may be any other non-zero value. + EXAMPLES -------- @@ -230,7 +241,7 @@ $ git branch -r staging/master staging/staging-linus staging/staging-next -$ git checkout -b staging staging/master +$ git switch -c staging staging/master ... ------------ diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index aa0cc8bd44..24c00c9384 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -121,7 +121,9 @@ depth is 4095. If specified, multiple packfiles may be created, which also prevents the creation of a bitmap index. The default is unlimited, unless the config variable - `pack.packSizeLimit` is set. + `pack.packSizeLimit` is set. Note that this option may result in + a larger and slower repository; see the discussion in + `pack.packSizeLimit`. -b:: --write-bitmap-index:: @@ -142,7 +144,7 @@ depth is 4095. --keep-pack=<pack-name>:: Exclude the given pack from repacking. This is the equivalent - of having `.keep` file on the pack. `<pack-name>` is the the + of having `.keep` file on the pack. `<pack-name>` is the pack file name without leading directory (e.g. `pack-123.pack`). The option could be specified multiple times to keep multiple packs. @@ -165,9 +167,35 @@ depth is 4095. Pass the `--delta-islands` option to `git-pack-objects`, see linkgit:git-pack-objects[1]. -Configuration +-g=<factor>:: +--geometric=<factor>:: + Arrange resulting pack structure so that each successive pack + contains at least `<factor>` times the number of objects as the + next-largest pack. ++ +`git repack` ensures this by determining a "cut" of packfiles that need +to be repacked into one in order to ensure a geometric progression. It +picks the smallest set of packfiles such that as many of the larger +packfiles (by count of objects contained in that pack) may be left +intact. ++ +Unlike other repack modes, the set of objects to pack is determined +uniquely by the set of packs being "rolled-up"; in other words, the +packs determined to need to be combined in order to restore a geometric +progression. ++ +When `--unpacked` is specified, loose objects are implicitly included in +this "roll-up", without respect to their reachability. This is subject +to change in the future. This option (implying a drastically different +repack mode) is not guaranteed to work with all other combinations of +option to `git repack`. + +CONFIGURATION ------------- +Various configuration variables affect packing, see +linkgit:git-config[1] (search for "pack" and "delta"). + By default, the command passes `--delta-base-offset` option to 'git pack-objects'; this typically results in slightly smaller packs, but the generated packs are incompatible with versions of Git older than @@ -178,6 +206,10 @@ need to set the configuration variable `repack.UseDeltaBaseOffset` to is unaffected by this option as the conversion is performed on the fly as needed in that case. +Delta compression is not used on objects larger than the +`core.bigFileThreshold` configuration variable and on files with the +attribute `delta` set to false. + SEE ALSO -------- linkgit:git-pack-objects[1] diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt index 246dc9943c..f271d758c3 100644 --- a/Documentation/git-replace.txt +++ b/Documentation/git-replace.txt @@ -123,10 +123,10 @@ The following format are available: CREATING REPLACEMENT OBJECTS ---------------------------- -linkgit:git-filter-branch[1], linkgit:git-hash-object[1] and -linkgit:git-rebase[1], among other git commands, can be used to create -replacement objects from existing objects. The `--edit` option can -also be used with 'git replace' to create a replacement object by +linkgit:git-hash-object[1], linkgit:git-rebase[1], and +https://github.com/newren/git-filter-repo[git-filter-repo], among other git commands, can be used to +create replacement objects from existing objects. The `--edit` option +can also be used with 'git replace' to create a replacement object by editing an existing object. If you want to replace many blobs, trees or commits that are part of a @@ -148,13 +148,13 @@ pending objects. SEE ALSO -------- linkgit:git-hash-object[1] -linkgit:git-filter-branch[1] linkgit:git-rebase[1] linkgit:git-tag[1] linkgit:git-branch[1] linkgit:git-commit[1] linkgit:git-var[1] linkgit:git[1] +https://github.com/newren/git-filter-repo[git-filter-repo] GIT --- diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index 95763d7581..4cfc883378 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -91,7 +91,7 @@ For such a test, you need to merge master and topic somehow. One way to do it is to pull master into the topic branch: ------------ - $ git checkout topic + $ git switch topic $ git merge master o---*---o---+ topic @@ -113,10 +113,10 @@ the upstream might have been advanced since the test merge `+`, in which case the final commit graph would look like this: ------------ - $ git checkout topic + $ git switch topic $ git merge master $ ... work on both topic and master branches - $ git checkout master + $ git switch master $ git merge topic o---*---o---+---o---o topic @@ -136,11 +136,11 @@ merges, you could blow away the test merge, and keep building on top of the tip before the test merge: ------------ - $ git checkout topic + $ git switch topic $ git merge master $ git reset --hard HEAD^ ;# rewind the test merge $ ... work on both topic and master branches - $ git checkout master + $ git switch master $ git merge topic o---*---o-------o---o topic diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 26e746c53f..252e2d4e47 100644 --- a/Documentation/git-reset.txt +++ b/Documentation/git-reset.txt @@ -8,33 +8,36 @@ git-reset - Reset current HEAD to the specified state SYNOPSIS -------- [verse] -'git reset' [-q] [<tree-ish>] [--] <paths>... -'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...] +'git reset' [-q] [<tree-ish>] [--] <pathspec>... +'git reset' [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>] +'git reset' (--patch | -p) [<tree-ish>] [--] [<pathspec>...] 'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>] DESCRIPTION ----------- -In the first and second form, copy entries from `<tree-ish>` to the index. -In the third form, set the current branch head (`HEAD`) to `<commit>`, +In the first three forms, copy entries from `<tree-ish>` to the index. +In the last form, set the current branch head (`HEAD`) to `<commit>`, optionally modifying index and working tree to match. The `<tree-ish>`/`<commit>` defaults to `HEAD` in all forms. -'git reset' [-q] [<tree-ish>] [--] <paths>...:: - This form resets the index entries for all `<paths>` to their - state at `<tree-ish>`. (It does not affect the working tree or - the current branch.) +'git reset' [-q] [<tree-ish>] [--] <pathspec>...:: +'git reset' [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]:: + These forms reset the index entries for all paths that match the + `<pathspec>` to their state at `<tree-ish>`. (It does not affect + the working tree or the current branch.) + -This means that `git reset <paths>` is the opposite of `git add -<paths>`. +This means that `git reset <pathspec>` is the opposite of `git add +<pathspec>`. This command is equivalent to +`git restore [--source=<tree-ish>] --staged <pathspec>...`. + -After running `git reset <paths>` to update the index entry, you can -use linkgit:git-checkout[1] to check the contents out of the index to -the working tree. -Alternatively, using linkgit:git-checkout[1] and specifying a commit, you +After running `git reset <pathspec>` to update the index entry, you can +use linkgit:git-restore[1] to check the contents out of the index to +the working tree. Alternatively, using linkgit:git-restore[1] +and specifying a commit with `--source`, you can copy the contents of a path out of a commit to the index and to the working tree in one go. -'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]:: +'git reset' (--patch | -p) [<tree-ish>] [--] [<pathspec>...]:: Interactively select hunks in the difference between the index and `<tree-ish>` (defaults to `HEAD`). The chosen hunks are applied in reverse to the index. @@ -84,10 +87,16 @@ but carries forward unmerged index entries. different between `<commit>` and `HEAD`. If a file that is different between `<commit>` and `HEAD` has local changes, reset is aborted. + +--[no-]recurse-submodules:: + When the working tree is updated, using --recurse-submodules will + also recursively reset the working tree of all active submodules + according to the commit recorded in the superproject, also setting + the submodules' HEAD to be detached at that commit. -- -If you want to undo a commit other than the latest on a branch, -linkgit:git-revert[1] is your friend. +See "Reset, restore and revert" in linkgit:git[1] for the differences +between the three commands. OPTIONS @@ -100,6 +109,26 @@ OPTIONS `reset.quiet` config option. `--quiet` and `--no-quiet` will override the default behavior. +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + +\--:: + Do not interpret any more arguments as options. + +<pathspec>...:: + Limits the paths affected by the operation. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. EXAMPLES -------- @@ -149,9 +178,9 @@ See also the `--amend` option to linkgit:git-commit[1]. Undo a commit, making it a topic branch:: + ------------ -$ git branch topic/wip <1> -$ git reset --hard HEAD~3 <2> -$ git checkout topic/wip <3> +$ git branch topic/wip <1> +$ git reset --hard HEAD~3 <2> +$ git switch topic/wip <3> ------------ + <1> You have made some commits, but realize they were premature @@ -232,13 +261,13 @@ working tree are not in any shape to be committed yet, but you need to get to the other branch for a quick bugfix. + ------------ -$ git checkout feature ;# you were working in "feature" branch and -$ work work work ;# got interrupted +$ git switch feature ;# you were working in "feature" branch and +$ work work work ;# got interrupted $ git commit -a -m "snapshot WIP" <1> -$ git checkout master +$ git switch master $ fix fix fix $ git commit ;# commit with real log -$ git checkout feature +$ git switch feature $ git reset --soft HEAD^ ;# go back to WIP state <2> $ git reset <3> ------------ @@ -279,18 +308,18 @@ reset it while keeping the changes in your working tree. + ------------ $ git tag start -$ git checkout -b branch1 +$ git switch -c branch1 $ edit $ git commit ... <1> $ edit -$ git checkout -b branch2 <2> +$ git switch -c branch2 <2> $ git reset --keep start <3> ------------ + <1> This commits your first edits in `branch1`. <2> In the ideal world, you could have realized that the earlier commit did not belong to the new topic when you created and switched - to `branch2` (i.e. `git checkout -b branch2 start`), but nobody is + to `branch2` (i.e. `git switch -c branch2 start`), but nobody is perfect. <3> But you can use `reset --keep` to remove the unwanted commit after you switched to `branch2`. diff --git a/Documentation/git-restore.txt b/Documentation/git-restore.txt new file mode 100644 index 0000000000..55bde91ef9 --- /dev/null +++ b/Documentation/git-restore.txt @@ -0,0 +1,219 @@ +git-restore(1) +============== + +NAME +---- +git-restore - Restore working tree files + +SYNOPSIS +-------- +[verse] +'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>... +'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul] +'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>...] + +DESCRIPTION +----------- +Restore specified paths in the working tree with some contents from a +restore source. If a path is tracked but does not exist in the restore +source, it will be removed to match the source. + +The command can also be used to restore the content in the index with +`--staged`, or restore both the working tree and the index with +`--staged --worktree`. + +By default, if `--staged` is given, the contents are restored from `HEAD`, +otherwise from the index. Use `--source` to restore from a different commit. + +See "Reset, restore and revert" in linkgit:git[1] for the differences +between the three commands. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +OPTIONS +------- +-s <tree>:: +--source=<tree>:: + Restore the working tree files with the content from the given + tree. It is common to specify the source tree by naming a + commit, branch or tag associated with it. ++ +If not specified, the contents are restored from `HEAD` if `--staged` is +given, otherwise from the index. ++ +As a special case, you may use `"A...B"` as a shortcut for the +merge base of `A` and `B` if there is exactly one merge base. You can +leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. + +-p:: +--patch:: + Interactively select hunks in the difference between the + restore source and the restore location. See the ``Interactive + Mode'' section of linkgit:git-add[1] to learn how to operate + the `--patch` mode. ++ +Note that `--patch` can accept no pathspec and will prompt to restore +all modified paths. + +-W:: +--worktree:: +-S:: +--staged:: + Specify the restore location. If neither option is specified, + by default the working tree is restored. Specifying `--staged` + will only restore the index. Specifying both restores both. + +-q:: +--quiet:: + Quiet, suppress feedback messages. Implies `--no-progress`. + +--progress:: +--no-progress:: + Progress status is reported on the standard error stream + by default when it is attached to a terminal, unless `--quiet` + is specified. This flag enables progress reporting even if not + attached to a terminal, regardless of `--quiet`. + +--ours:: +--theirs:: + When restoring files in the working tree from the index, use + stage #2 ('ours') or #3 ('theirs') for unmerged paths. ++ +Note that during `git rebase` and `git pull --rebase`, 'ours' and +'theirs' may appear swapped. See the explanation of the same options +in linkgit:git-checkout[1] for details. + +-m:: +--merge:: + When restoring files on the working tree from the index, + recreate the conflicted merge in the unmerged paths. + +--conflict=<style>:: + The same as `--merge` option above, but changes the way the + conflicting hunks are presented, overriding the + `merge.conflictStyle` configuration variable. Possible values + are "merge" (default) and "diff3" (in addition to what is + shown by "merge" style, shows the original contents). + +--ignore-unmerged:: + When restoring files on the working tree from the index, do + not abort the operation if there are unmerged entries and + neither `--ours`, `--theirs`, `--merge` or `--conflict` is + specified. Unmerged paths on the working tree are left alone. + +--ignore-skip-worktree-bits:: + In sparse checkout mode, by default is to only update entries + matched by `<pathspec>` and sparse patterns in + $GIT_DIR/info/sparse-checkout. This option ignores the sparse + patterns and unconditionally restores any files in + `<pathspec>`. + +--recurse-submodules:: +--no-recurse-submodules:: + If `<pathspec>` names an active submodule and the restore location + includes the working tree, the submodule will only be updated if + this option is given, in which case its working tree will be + restored to the commit recorded in the superproject, and any local + modifications overwritten. If nothing (or + `--no-recurse-submodules`) is used, submodules working trees will + not be updated. Just like linkgit:git-checkout[1], this will detach + `HEAD` of the submodule. + +--overlay:: +--no-overlay:: + In overlay mode, the command never removes files when + restoring. In no-overlay mode, tracked files that do not + appear in the `--source` tree are removed, to make them match + `<tree>` exactly. The default is no-overlay mode. + +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. + +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). + +\--:: + Do not interpret any more arguments as options. + +<pathspec>...:: + Limits the paths affected by the operation. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. + +EXAMPLES +-------- + +The following sequence switches to the `master` branch, reverts the +`Makefile` to two revisions back, deletes hello.c by mistake, and gets +it back from the index. + +------------ +$ git switch master +$ git restore --source master~2 Makefile <1> +$ rm -f hello.c +$ git restore hello.c <2> +------------ + +<1> take a file out of another commit +<2> restore hello.c from the index + +If you want to restore _all_ C source files to match the version in +the index, you can say + +------------ +$ git restore '*.c' +------------ + +Note the quotes around `*.c`. The file `hello.c` will also be +restored, even though it is no longer in the working tree, because the +file globbing is used to match entries in the index (not in the +working tree by the shell). + +To restore all files in the current directory + +------------ +$ git restore . +------------ + +or to restore all working tree files with 'top' pathspec magic (see +linkgit:gitglossary[7]) + +------------ +$ git restore :/ +------------ + +To restore a file in the index to match the version in `HEAD` (this is +the same as using linkgit:git-reset[1]) + +------------ +$ git restore --staged hello.c +------------ + +or you can restore both the index and the working tree (this the same +as using linkgit:git-checkout[1]) + +------------ +$ git restore --source=HEAD --staged --worktree hello.c +------------ + +or the short form which is more practical but less readable: + +------------ +$ git restore -s@ -SW hello.c +------------ + +SEE ALSO +-------- +linkgit:git-checkout[1], +linkgit:git-reset[1] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index 88609ff435..20bb8e8217 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -9,100 +9,13 @@ git-rev-list - Lists commit objects in reverse chronological order SYNOPSIS -------- [verse] -'git rev-list' [ --max-count=<number> ] - [ --skip=<number> ] - [ --max-age=<timestamp> ] - [ --min-age=<timestamp> ] - [ --sparse ] - [ --merges ] - [ --no-merges ] - [ --min-parents=<number> ] - [ --no-min-parents ] - [ --max-parents=<number> ] - [ --no-max-parents ] - [ --first-parent ] - [ --remove-empty ] - [ --full-history ] - [ --not ] - [ --all ] - [ --branches[=<pattern>] ] - [ --tags[=<pattern>] ] - [ --remotes[=<pattern>] ] - [ --glob=<glob-pattern> ] - [ --ignore-missing ] - [ --stdin ] - [ --quiet ] - [ --topo-order ] - [ --parents ] - [ --timestamp ] - [ --left-right ] - [ --left-only ] - [ --right-only ] - [ --cherry-mark ] - [ --cherry-pick ] - [ --encoding=<encoding> ] - [ --(author|committer|grep)=<pattern> ] - [ --regexp-ignore-case | -i ] - [ --extended-regexp | -E ] - [ --fixed-strings | -F ] - [ --date=<format>] - [ [ --objects | --objects-edge | --objects-edge-aggressive ] - [ --unpacked ] - [ --filter=<filter-spec> [ --filter-print-omitted ] ] ] - [ --missing=<missing-action> ] - [ --pretty | --header ] - [ --bisect ] - [ --bisect-vars ] - [ --bisect-all ] - [ --merge ] - [ --reverse ] - [ --walk-reflogs ] - [ --no-walk ] [ --do-walk ] - [ --count ] - [ --use-bitmap-index ] - <commit>... [ \-- <paths>... ] +'git rev-list' [<options>] <commit>... [[--] <path>...] DESCRIPTION ----------- -List commits that are reachable by following the `parent` links from the -given commit(s), but exclude commits that are reachable from the one(s) -given with a '{caret}' in front of them. The output is given in reverse -chronological order by default. - -You can think of this as a set operation. Commits given on the command -line form a set of commits that are reachable from any of them, and then -commits reachable from any of the ones given with '{caret}' in front are -subtracted from that set. The remaining commits are what comes out in the -command's output. Various other options and paths parameters can be used -to further limit the result. - -Thus, the following command: - ------------------------------------------------------------------------ - $ git rev-list foo bar ^baz ------------------------------------------------------------------------ - -means "list all the commits which are reachable from 'foo' or 'bar', but -not from 'baz'". - -A special notation "'<commit1>'..'<commit2>'" can be used as a -short-hand for "{caret}'<commit1>' '<commit2>'". For example, either of -the following may be used interchangeably: - ------------------------------------------------------------------------ - $ git rev-list origin..HEAD - $ git rev-list HEAD ^origin ------------------------------------------------------------------------ - -Another special notation is "'<commit1>'...'<commit2>'" which is useful -for merges. The resulting set of commits is the symmetric difference -between the two operands. The following two commands are equivalent: - ------------------------------------------------------------------------ - $ git rev-list A B --not $(git merge-base --all A B) - $ git rev-list A...B ------------------------------------------------------------------------ +:git-rev-list: 1 +include::rev-list-description.txt[] 'rev-list' is a very essential Git command, since it provides the ability to build and traverse commit ancestry graphs. For @@ -118,6 +31,99 @@ include::rev-list-options.txt[] include::pretty-formats.txt[] +EXAMPLES +-------- + +* Print the list of commits reachable from the current branch. ++ +---------- +git rev-list HEAD +---------- + +* Print the list of commits on this branch, but not present in the + upstream branch. ++ +---------- +git rev-list @{upstream}..HEAD +---------- + +* Format commits with their author and commit message (see also the + porcelain linkgit:git-log[1]). ++ +---------- +git rev-list --format=medium HEAD +---------- + +* Format commits along with their diffs (see also the porcelain + linkgit:git-log[1], which can do this in a single process). ++ +---------- +git rev-list HEAD | +git diff-tree --stdin --format=medium -p +---------- + +* Print the list of commits on the current branch that touched any + file in the `Documentation` directory. ++ +---------- +git rev-list HEAD -- Documentation/ +---------- + +* Print the list of commits authored by you in the past year, on + any branch, tag, or other ref. ++ +---------- +git rev-list --author=you@example.com --since=1.year.ago --all +---------- + +* Print the list of objects reachable from the current branch (i.e., all + commits and the blobs and trees they contain). ++ +---------- +git rev-list --objects HEAD +---------- + +* Compare the disk size of all reachable objects, versus those + reachable from reflogs, versus the total packed size. This can tell + you whether running `git repack -ad` might reduce the repository size + (by dropping unreachable objects), and whether expiring reflogs might + help. ++ +---------- +# reachable objects +git rev-list --disk-usage --objects --all +# plus reflogs +git rev-list --disk-usage --objects --all --reflog +# total disk size used +du -c .git/objects/pack/*.pack .git/objects/??/* +# alternative to du: add up "size" and "size-pack" fields +git count-objects -v +---------- + +* Report the disk size of each branch, not including objects used by the + current branch. This can find outliers that are contributing to a + bloated repository size (e.g., because somebody accidentally committed + large build artifacts). ++ +---------- +git for-each-ref --format='%(refname)' | +while read branch +do + size=$(git rev-list --disk-usage --objects HEAD..$branch) + echo "$size $branch" +done | +sort -n +---------- + +* Compare the on-disk size of branches in one group of refs, excluding + another. If you co-mingle objects from multiple remotes in a single + repository, this can show which remotes are contributing to the + repository size (taking the size of `origin` as a baseline). ++ +---------- +git rev-list --disk-usage --objects --remotes=$suspect --not --remotes=origin +---------- + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index e72d332b83..6b8ca085aa 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -109,6 +109,10 @@ names an existing object that is a commit-ish (i.e. a commit, or an annotated tag that points at a commit). To make sure that `$VAR` names an existing object of any type, `git rev-parse "$VAR^{object}"` can be used. ++ +Note that if you are verifying a name from an untrusted source, it is +wise to use `--end-of-options` so that the name argument is not mistaken +for another option. -q:: --quiet:: @@ -208,6 +212,18 @@ Options for Files Only the names of the variables are listed, not their value, even if they are set. +--path-format=(absolute|relative):: + Controls the behavior of certain other options. If specified as absolute, the + paths printed by those options will be absolute and canonical. If specified as + relative, the paths will be relative to the current working directory if that + is possible. The default is option specific. ++ +This option may be specified multiple times and affects only the arguments that +follow it on the command line, either to the end of the command line or the next +instance of this option. + +The following options are modified by `--path-format`: + --git-dir:: Show `$GIT_DIR` if defined. Otherwise show the path to the .git directory. The path shown, when relative, is @@ -217,13 +233,42 @@ If `$GIT_DIR` is not defined and the current directory is not detected to lie in a Git repository or work tree print a message to stderr and exit with nonzero status. +--git-common-dir:: + Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`. + +--resolve-git-dir <path>:: + Check if <path> is a valid repository or a gitfile that + points at a valid repository, and print the location of the + repository. If <path> is a gitfile then the resolved path + to the real repository is printed. + +--git-path <path>:: + Resolve "$GIT_DIR/<path>" and takes other path relocation + variables such as $GIT_OBJECT_DIRECTORY, + $GIT_INDEX_FILE... into account. For example, if + $GIT_OBJECT_DIRECTORY is set to /foo/bar then "git rev-parse + --git-path objects/abc" returns /foo/bar/abc. + +--show-toplevel:: + Show the (by default, absolute) path of the top-level directory + of the working tree. If there is no working tree, report an error. + +--show-superproject-working-tree:: + Show the absolute path of the root of the superproject's + working tree (if exists) that uses the current repository as + its submodule. Outputs nothing if the current repository is + not used as a submodule by any project. + +--shared-index-path:: + Show the path to the shared index file in split index mode, or + empty if not in split-index mode. + +The following options are unaffected by `--path-format`: + --absolute-git-dir:: Like `--git-dir`, but its output is always the canonicalized absolute path. ---git-common-dir:: - Show `$GIT_COMMON_DIR` if defined, else `$GIT_DIR`. - --is-inside-git-dir:: When the current working directory is below the repository directory print "true", otherwise "false". @@ -238,19 +283,6 @@ print a message to stderr and exit with nonzero status. --is-shallow-repository:: When the repository is shallow print "true", otherwise "false". ---resolve-git-dir <path>:: - Check if <path> is a valid repository or a gitfile that - points at a valid repository, and print the location of the - repository. If <path> is a gitfile then the resolved path - to the real repository is printed. - ---git-path <path>:: - Resolve "$GIT_DIR/<path>" and takes other path relocation - variables such as $GIT_OBJECT_DIRECTORY, - $GIT_INDEX_FILE... into account. For example, if - $GIT_OBJECT_DIRECTORY is set to /foo/bar then "git rev-parse - --git-path objects/abc" returns /foo/bar/abc. - --show-cdup:: When the command is invoked from a subdirectory, show the path of the top-level directory relative to the current @@ -261,18 +293,12 @@ print a message to stderr and exit with nonzero status. path of the current directory relative to the top-level directory. ---show-toplevel:: - Show the absolute path of the top-level directory. - ---show-superproject-working-tree:: - Show the absolute path of the root of the superproject's - working tree (if exists) that uses the current repository as - its submodule. Outputs nothing if the current repository is - not used as a submodule by any project. +--show-object-format[=(storage|input|output)]:: + Show the object format (hash algorithm) used for the repository + for storage inside the `.git` directory, input, or output. For + input, multiple algorithms may be printed, space-separated. + If not specified, the default is "storage". ---shared-index-path:: - Show the path to the shared index file in split index mode, or - empty if not in split-index mode. Other Options ~~~~~~~~~~~~~ @@ -438,7 +464,7 @@ $ git rev-parse --verify HEAD * Print the commit object name from the revision in the $REV shell variable: + ------------ -$ git rev-parse --verify $REV^{commit} +$ git rev-parse --verify --end-of-options $REV^{commit} ------------ + This will error out if $REV is empty or not a valid revision. @@ -446,7 +472,7 @@ This will error out if $REV is empty or not a valid revision. * Similar to above: + ------------ -$ git rev-parse --default master --verify $REV +$ git rev-parse --default master --verify --end-of-options $REV ------------ + but if $REV is empty, the commit object name from master will be printed. diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index 0c82ca5bc0..bb92a4a451 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -9,9 +9,7 @@ SYNOPSIS -------- [verse] 'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] [-S[<keyid>]] <commit>... -'git revert' --continue -'git revert' --quit -'git revert' --abort +'git revert' (--continue | --skip | --abort | --quit) DESCRIPTION ----------- @@ -26,10 +24,13 @@ effect of some earlier commits (often only a faulty one). If you want to throw away all uncommitted changes in your working directory, you should see linkgit:git-reset[1], particularly the `--hard` option. If you want to extract specific files as they were in another commit, you -should see linkgit:git-checkout[1], specifically the `git checkout -<commit> -- <filename>` syntax. Take care with these alternatives as +should see linkgit:git-restore[1], specifically the `--source` +option. Take care with these alternatives as both will discard uncommitted changes in your working directory. +See "Reset, restore and revert" in linkgit:git[1] for the differences +between the three commands. + OPTIONS ------- <commit>...:: @@ -89,13 +90,16 @@ effect to your index in a row. -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign commits. The `keyid` argument is optional and defaults to the committer identity; if specified, it must be - stuck to the option without a space. + stuck to the option without a space. `--no-gpg-sign` is useful to + countermand both `commit.gpgSign` configuration variable, and + earlier `--gpg-sign`. -s:: --signoff:: - Add Signed-off-by line at the end of the commit message. + Add a `Signed-off-by` trailer at the end of the commit message. See the signoff option in linkgit:git-commit[1] for more information. --strategy=<strategy>:: diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index b5c46223c4..26e9b28470 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -8,33 +8,42 @@ git-rm - Remove files from the working tree and from the index SYNOPSIS -------- [verse] -'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>... +'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] + [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]] + [--] [<pathspec>...] DESCRIPTION ----------- -Remove files from the index, or from the working tree and the index. -`git rm` will not remove a file from just your working directory. -(There is no option to remove a file only from the working tree -and yet keep it in the index; use `/bin/rm` if you want to do that.) -The files being removed have to be identical to the tip of the branch, -and no updates to their contents can be staged in the index, +Remove files matching pathspec from the index, or from the working tree +and the index. `git rm` will not remove a file from just your working +directory. (There is no option to remove a file only from the working +tree and yet keep it in the index; use `/bin/rm` if you want to do +that.) The files being removed have to be identical to the tip of the +branch, and no updates to their contents can be staged in the index, though that default behavior can be overridden with the `-f` option. When `--cached` is given, the staged content has to match either the tip of the branch or the file on disk, -allowing the file to be removed from just the index. +allowing the file to be removed from just the index. When +sparse-checkouts are in use (see linkgit:git-sparse-checkout[1]), +`git rm` will only remove paths within the sparse-checkout patterns. OPTIONS ------- -<file>...:: - Files to remove. Fileglobs (e.g. `*.c`) can be given to - remove all matching files. If you want Git to expand - file glob characters, you may need to shell-escape them. - A leading directory name - (e.g. `dir` to remove `dir/file1` and `dir/file2`) can be - given to remove all files in the directory, and recursively - all sub-directories, - but this requires the `-r` option to be explicitly given. +<pathspec>...:: + Files to remove. A leading directory name (e.g. `dir` to remove + `dir/file1` and `dir/file2`) can be given to remove all files in + the directory, and recursively all sub-directories, but this + requires the `-r` option to be explicitly given. ++ +The command removes only the paths that are known to Git. ++ +File globbing matches across directory boundaries. Thus, given two +directories `d` and `d2`, there is a difference between using +`git rm 'd*'` and `git rm 'd/*'`, as the former will also remove all +of directory `d2`. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. -f:: --force:: @@ -68,19 +77,19 @@ OPTIONS `git rm` normally outputs one line (in the form of an `rm` command) for each file removed. This option suppresses that output. +--pathspec-from-file=<file>:: + Pathspec is passed in `<file>` instead of commandline args. If + `<file>` is exactly `-` then standard input is used. Pathspec + elements are separated by LF or CR/LF. Pathspec elements can be + quoted as explained for the configuration variable `core.quotePath` + (see linkgit:git-config[1]). See also `--pathspec-file-nul` and + global `--literal-pathspecs`. -DISCUSSION ----------- - -The <file> list given to the command can be exact pathnames, -file glob patterns, or leading directory names. The command -removes only the paths that are known to Git. Giving the name of -a file that you have not told Git about does not remove that file. +--pathspec-file-nul:: + Only meaningful with `--pathspec-from-file`. Pathspec elements are + separated with NUL character and all other characters are taken + literally (including newlines and quotes). -File globbing matches across directory boundaries. Thus, given -two directories `d` and `d2`, there is a difference between -using `git rm 'd*'` and `git rm 'd/*'`, as the former will -also remove all of directory `d2`. REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM -------------------------------------------------------- diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 504ae7fe76..3db4eab4ba 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -167,6 +167,14 @@ Sending `sendemail.envelopeSender` configuration variable; if that is unspecified, choosing the envelope sender is left to your MTA. +--sendmail-cmd=<command>:: + Specify a command to run to send the email. The command should + be sendmail-like; specifically, it must support the `-i` option. + The command will be executed in the shell if necessary. Default + is the value of `sendemail.sendmailcmd`. If unspecified, and if + --smtp-server is also unspecified, git-send-email will search + for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH. + --smtp-encryption=<encryption>:: Specify the encryption to use, either 'ssl' or 'tls'. Any other value reverts to plain SMTP. Default is the value of @@ -211,13 +219,16 @@ a password is obtained using 'git-credential'. --smtp-server=<host>:: If set, specifies the outgoing SMTP server to use (e.g. - `smtp.example.com` or a raw IP address). Alternatively it can - specify a full pathname of a sendmail-like program instead; - the program must support the `-i` option. Default value can - be specified by the `sendemail.smtpServer` configuration - option; the built-in default is to search for `sendmail` in - `/usr/sbin`, `/usr/lib` and $PATH if such program is - available, falling back to `localhost` otherwise. + `smtp.example.com` or a raw IP address). If unspecified, and if + `--sendmail-cmd` is also unspecified, the default is to search + for `sendmail` in `/usr/sbin`, `/usr/lib` and $PATH if such a + program is available, falling back to `localhost` otherwise. ++ +For backward compatibility, this option can also specify a full pathname +of a sendmail-like program instead; the program must support the `-i` +option. This method does not support passing arguments or using plain +command names. For those use cases, consider using `--sendmail-cmd` +instead. --smtp-server-port=<port>:: Specifies a port different from the default port (SMTP @@ -278,6 +289,14 @@ must be used for each option. Automating ~~~~~~~~~~ +--no-[to|cc|bcc]:: + Clears any list of "To:", "Cc:", "Bcc:" addresses previously + set via config. + +--no-identity:: + Clears the previously read value of `sendemail.identity` set + via config, if any. + --to-cmd=<command>:: Specify a command to execute once per patch file which should generate patch file specific "To:" entries. @@ -305,7 +324,7 @@ Automating the value of `sendemail.identity`. --[no-]signed-off-by-cc:: - If this is set, add emails found in Signed-off-by: or Cc: lines to the + If this is set, add emails found in the `Signed-off-by` trailer or Cc: lines to the cc list. Default is the value of `sendemail.signedoffbycc` configuration value; if that is unspecified, default to --signed-off-by-cc. @@ -332,7 +351,7 @@ Automating except for self (use 'self' for that). - 'bodycc' will avoid including anyone mentioned in Cc lines in the patch body (commit message) except for self (use 'self' for that). -- 'sob' will avoid including anyone mentioned in Signed-off-by lines except +- 'sob' will avoid including anyone mentioned in the Signed-off-by trailers except for self (use 'self' for that). - 'misc-by' will avoid including anyone mentioned in Acked-by, Reviewed-by, Tested-by and other "-by" lines in the patch body, @@ -478,16 +497,22 @@ Use gmail as the smtp server To use 'git send-email' to send your patches through the GMail SMTP server, edit ~/.gitconfig to specify your account settings: - [sendemail] - smtpEncryption = tls - smtpServer = smtp.gmail.com - smtpUser = yourname@gmail.com - smtpServerPort = 587 +---- +[sendemail] + smtpEncryption = tls + smtpServer = smtp.gmail.com + smtpUser = yourname@gmail.com + smtpServerPort = 587 +---- -If you have multifactor authentication setup on your gmail account, you will +If you have multi-factor authentication set up on your Gmail account, you will need to generate an app-specific password for use with 'git send-email'. Visit https://security.google.com/settings/security/apppasswords to create it. +If you do not have multi-factor authentication set up on your Gmail account, +you will need to allow less secure app access. Visit +https://myaccount.google.com/lesssecureapps to enable it. + Once your commits are ready to be sent to the mailing list, run the following commands: diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index bc80905a8a..c9c7f3065c 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -47,9 +47,38 @@ OPTIONS Each pretty-printed commit will be rewrapped before it is shown. +--group=<type>:: + Group commits based on `<type>`. If no `--group` option is + specified, the default is `author`. `<type>` is one of: ++ +-- + - `author`, commits are grouped by author + - `committer`, commits are grouped by committer (the same as `-c`) + - `trailer:<field>`, the `<field>` is interpreted as a case-insensitive + commit message trailer (see linkgit:git-interpret-trailers[1]). For + example, if your project uses `Reviewed-by` trailers, you might want + to see who has been reviewing with + `git shortlog -ns --group=trailer:reviewed-by`. ++ +Note that commits that do not include the trailer will not be counted. +Likewise, commits with multiple trailers (e.g., multiple signoffs) may +be counted more than once (but only once per unique trailer value in +that commit). ++ +Shortlog will attempt to parse each trailer value as a `name <email>` +identity. If successful, the mailmap is applied and the email is omitted +unless the `--email` option is specified. If the value cannot be parsed +as an identity, it will be taken literally and completely. +-- ++ +If `--group` is specified multiple times, commits are counted under each +value (but again, only once per unique value in that commit). For +example, `git shortlog --group=author --group=trailer:co-authored-by` +counts both authors and co-authors. + -c:: --committer:: - Collect and show committer identities instead of authors. + This is an alias for `--group=committer`. -w[<width>[,<indent1>[,<indent2>]]]:: Linewrap the output by wrapping each line at `width`. The first @@ -76,14 +105,17 @@ them. Paths may need to be prefixed with `--` to separate them from options or the revision range, when confusion arises. +:git-shortlog: 1 +include::rev-list-options.txt[] + MAPPING AUTHORS --------------- -The `.mailmap` feature is used to coalesce together commits by the same -person in the shortlog, where their name and/or email address was -spelled differently. +See linkgit:gitmailmap[5]. -include::mailmap.txt[] +Note that if `git shortlog` is run outside of a repository (to process +log contents on standard input), it will look for a `.mailmap` file in +the current directory. GIT --- diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.txt index 424e4ba84c..e49318a5a0 100644 --- a/Documentation/git-show-index.txt +++ b/Documentation/git-show-index.txt @@ -9,7 +9,7 @@ git-show-index - Show packed archive index SYNOPSIS -------- [verse] -'git show-index' +'git show-index' [--object-format=<hash-algorithm>] DESCRIPTION @@ -36,6 +36,17 @@ Note that you can get more information on a packfile by calling linkgit:git-verify-pack[1]. However, as this command considers only the index file itself, it's both faster and more flexible. +OPTIONS +------- + +--object-format=<hash-algorithm>:: + Specify the given object format (hash algorithm) for the index file. The + valid values are 'sha1' and (if enabled) 'sha256'. The default is the + algorithm for the current repository (set by `extensions.objectFormat`), or + 'sha1' if no value is set or outside a repository.. ++ +include::object-format-disclaimer.txt[] + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt index fcf528c1b3..2b1bc7288d 100644 --- a/Documentation/git-show.txt +++ b/Documentation/git-show.txt @@ -45,10 +45,13 @@ include::pretty-options.txt[] include::pretty-formats.txt[] -COMMON DIFF OPTIONS -------------------- +DIFF FORMATTING +--------------- +The options below can be used to change the way `git show` generates +diff output. :git-log: 1 +:diff-merges-default: `dense-combined` include::diff-options.txt[] include::diff-generate-patch.txt[] diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt new file mode 100644 index 0000000000..fdcf43f87c --- /dev/null +++ b/Documentation/git-sparse-checkout.txt @@ -0,0 +1,253 @@ +git-sparse-checkout(1) +====================== + +NAME +---- +git-sparse-checkout - Initialize and modify the sparse-checkout +configuration, which reduces the checkout to a set of paths +given by a list of patterns. + + +SYNOPSIS +-------- +[verse] +'git sparse-checkout <subcommand> [options]' + + +DESCRIPTION +----------- + +Initialize and modify the sparse-checkout configuration, which reduces +the checkout to a set of paths given by a list of patterns. + +THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR, AND THE BEHAVIOR OF OTHER +COMMANDS IN THE PRESENCE OF SPARSE-CHECKOUTS, WILL LIKELY CHANGE IN +THE FUTURE. + + +COMMANDS +-------- +'list':: + Describe the patterns in the sparse-checkout file. + +'init':: + Enable the `core.sparseCheckout` setting. If the + sparse-checkout file does not exist, then populate it with + patterns that match every file in the root directory and + no other directories, then will remove all directories tracked + by Git. Add patterns to the sparse-checkout file to + repopulate the working directory. ++ +To avoid interfering with other worktrees, it first enables the +`extensions.worktreeConfig` setting and makes sure to set the +`core.sparseCheckout` setting in the worktree-specific config file. ++ +When `--cone` is provided, the `core.sparseCheckoutCone` setting is +also set, allowing for better performance with a limited set of +patterns (see 'CONE PATTERN SET' below). ++ +Use the `--[no-]sparse-index` option to toggle the use of the sparse +index format. This reduces the size of the index to be more closely +aligned with your sparse-checkout definition. This can have significant +performance advantages for commands such as `git status` or `git add`. +This feature is still experimental. Some commands might be slower with +a sparse index until they are properly integrated with the feature. ++ +**WARNING:** Using a sparse index requires modifying the index in a way +that is not completely understood by external tools. If you have trouble +with this compatibility, then run `git sparse-checkout init --no-sparse-index` +to rewrite your index to not be sparse. Older versions of Git will not +understand the sparse directory entries index extension and may fail to +interact with your repository until it is disabled. + +'set':: + Write a set of patterns to the sparse-checkout file, as given as + a list of arguments following the 'set' subcommand. Update the + working directory to match the new patterns. Enable the + core.sparseCheckout config setting if it is not already enabled. ++ +When the `--stdin` option is provided, the patterns are read from +standard in as a newline-delimited list instead of from the arguments. ++ +When `core.sparseCheckoutCone` is enabled, the input list is considered a +list of directories instead of sparse-checkout patterns. The command writes +patterns to the sparse-checkout file to include all files contained in those +directories (recursively) as well as files that are siblings of ancestor +directories. The input format matches the output of `git ls-tree --name-only`. +This includes interpreting pathnames that begin with a double quote (") as +C-style quoted strings. + +'add':: + Update the sparse-checkout file to include additional patterns. + By default, these patterns are read from the command-line arguments, + but they can be read from stdin using the `--stdin` option. When + `core.sparseCheckoutCone` is enabled, the given patterns are interpreted + as directory names as in the 'set' subcommand. + +'reapply':: + Reapply the sparsity pattern rules to paths in the working tree. + Commands like merge or rebase can materialize paths to do their + work (e.g. in order to show you a conflict), and other + sparse-checkout commands might fail to sparsify an individual file + (e.g. because it has unstaged changes or conflicts). In such + cases, it can make sense to run `git sparse-checkout reapply` later + after cleaning up affected paths (e.g. resolving conflicts, undoing + or committing changes, etc.). + +'disable':: + Disable the `core.sparseCheckout` config setting, and restore the + working directory to include all files. Leaves the sparse-checkout + file intact so a later 'git sparse-checkout init' command may + return the working directory to the same state. + +SPARSE CHECKOUT +--------------- + +"Sparse checkout" allows populating the working directory sparsely. +It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell +Git whether a file in the working directory is worth looking at. If +the skip-worktree bit is set, then the file is ignored in the working +directory. Git will not populate the contents of those files, which +makes a sparse checkout helpful when working in a repository with many +files, but only a few are important to the current user. + +The `$GIT_DIR/info/sparse-checkout` file is used to define the +skip-worktree reference bitmap. When Git updates the working +directory, it updates the skip-worktree bits in the index based +on this file. The files matching the patterns in the file will +appear in the working directory, and the rest will not. + +To enable the sparse-checkout feature, run `git sparse-checkout init` to +initialize a simple sparse-checkout file and enable the `core.sparseCheckout` +config setting. Then, run `git sparse-checkout set` to modify the patterns in +the sparse-checkout file. + +To repopulate the working directory with all files, use the +`git sparse-checkout disable` command. + + +FULL PATTERN SET +---------------- + +By default, the sparse-checkout file uses the same syntax as `.gitignore` +files. + +While `$GIT_DIR/info/sparse-checkout` is usually used to specify what +files are included, you can also specify what files are _not_ included, +using negative patterns. For example, to remove the file `unwanted`: + +---------------- +/* +!unwanted +---------------- + + +CONE PATTERN SET +---------------- + +The full pattern set allows for arbitrary pattern matches and complicated +inclusion/exclusion rules. These can result in O(N*M) pattern matches when +updating the index, where N is the number of patterns and M is the number +of paths in the index. To combat this performance issue, a more restricted +pattern set is allowed when `core.sparseCheckoutCone` is enabled. + +The accepted patterns in the cone pattern set are: + +1. *Recursive:* All paths inside a directory are included. + +2. *Parent:* All files immediately inside a directory are included. + +In addition to the above two patterns, we also expect that all files in the +root directory are included. If a recursive pattern is added, then all +leading directories are added as parent patterns. + +By default, when running `git sparse-checkout init`, the root directory is +added as a parent pattern. At this point, the sparse-checkout file contains +the following patterns: + +---------------- +/* +!/*/ +---------------- + +This says "include everything in root, but nothing two levels below root." + +When in cone mode, the `git sparse-checkout set` subcommand takes a list of +directories instead of a list of sparse-checkout patterns. In this mode, +the command `git sparse-checkout set A/B/C` sets the directory `A/B/C` as +a recursive pattern, the directories `A` and `A/B` are added as parent +patterns. The resulting sparse-checkout file is now + +---------------- +/* +!/*/ +/A/ +!/A/*/ +/A/B/ +!/A/B/*/ +/A/B/C/ +---------------- + +Here, order matters, so the negative patterns are overridden by the positive +patterns that appear lower in the file. + +If `core.sparseCheckoutCone=true`, then Git will parse the sparse-checkout file +expecting patterns of these types. Git will warn if the patterns do not match. +If the patterns do match the expected format, then Git will use faster hash- +based algorithms to compute inclusion in the sparse-checkout. + +In the cone mode case, the `git sparse-checkout list` subcommand will list the +directories that define the recursive patterns. For the example sparse-checkout +file above, the output is as follows: + +-------------------------- +$ git sparse-checkout list +A/B/C +-------------------------- + +If `core.ignoreCase=true`, then the pattern-matching algorithm will use a +case-insensitive check. This corrects for case mismatched filenames in the +'git sparse-checkout set' command to reflect the expected cone in the working +directory. + + +SUBMODULES +---------- + +If your repository contains one or more submodules, then submodules +are populated based on interactions with the `git submodule` command. +Specifically, `git submodule init -- <path>` will ensure the submodule +at `<path>` is present, while `git submodule deinit [-f] -- <path>` +will remove the files for the submodule at `<path>` (including any +untracked files, uncommitted changes, and unpushed history). Similar +to how sparse-checkout removes files from the working tree but still +leaves entries in the index, deinitialized submodules are removed from +the working directory but still have an entry in the index. + +Since submodules may have unpushed changes or untracked files, +removing them could result in data loss. Thus, changing sparse +inclusion/exclusion rules will not cause an already checked out +submodule to be removed from the working copy. Said another way, just +as `checkout` will not cause submodules to be automatically removed or +initialized even when switching between branches that remove or add +submodules, using `sparse-checkout` to reduce or expand the scope of +"interesting" files will not cause submodules to be automatically +deinitialized or initialized either. + +Further, the above facts mean that there are multiple reasons that +"tracked" files might not be present in the working copy: sparsity +pattern application from sparse-checkout, and submodule initialization +state. Thus, commands like `git grep` that work on tracked files in +the working copy may return results that are limited by either or both +of these restrictions. + + +SEE ALSO +-------- + +linkgit:git-read-tree[1] +linkgit:gitignore[5] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.txt index e31ea7d303..be6084ccef 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.txt @@ -8,13 +8,14 @@ git-stash - Stash the changes in a dirty working directory away SYNOPSIS -------- [verse] -'git stash' list [<options>] -'git stash' show [<options>] [<stash>] +'git stash' list [<log-options>] +'git stash' show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>] 'git stash' drop [-q|--quiet] [<stash>] 'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>] 'git stash' branch <branchname> [<stash>] 'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all] [-m|--message <message>] + [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]] 'git stash' clear 'git stash' create [<message>] @@ -43,10 +44,10 @@ created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}` is also possible). Stashes may also be referenced by specifying just the stash index (e.g. the integer `n` is equivalent to `stash@{n}`). -OPTIONS -------- +COMMANDS +-------- -push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--] [<pathspec>...]:: +push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]:: Save your local modifications to a new 'stash entry' and roll them back to HEAD (in the working tree and in the index). @@ -56,41 +57,17 @@ push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q For quickly making a snapshot, you can omit "push". In this mode, non-option arguments are not allowed to prevent a misspelled subcommand from making an unwanted stash entry. The two exceptions to this -are `stash -p` which acts as alias for `stash push -p` and pathspecs, +are `stash -p` which acts as alias for `stash push -p` and pathspec elements, which are allowed after a double hyphen `--` for disambiguation. -+ -When pathspec is given to 'git stash push', the new stash entry records the -modified states only for the files that match the pathspec. The index -entries and working tree files are then rolled back to the state in -HEAD only for these files, too, leaving files that do not match the -pathspec intact. -+ -If the `--keep-index` option is used, all changes already added to the -index are left intact. -+ -If the `--include-untracked` option is used, all untracked files are also -stashed and then cleaned up with `git clean`, leaving the working directory -in a very clean state. If the `--all` option is used instead then the -ignored files are stashed and cleaned in addition to the untracked files. -+ -With `--patch`, you can interactively select hunks from the diff -between HEAD and the working tree to be stashed. The stash entry is -constructed such that its index state is the same as the index state -of your repository, and its worktree contains only the changes you -selected interactively. The selected changes are then rolled back -from your worktree. See the ``Interactive Mode'' section of -linkgit:git-add[1] to learn how to operate the `--patch` mode. -+ -The `--patch` option implies `--keep-index`. You can use -`--no-keep-index` to override this. save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]:: This option is deprecated in favour of 'git stash push'. It - differs from "stash push" in that it cannot take pathspecs, - and any non-option arguments form the message. + differs from "stash push" in that it cannot take pathspec. + Instead, all non-option arguments are concatenated to form the stash + message. -list [<options>]:: +list [<log-options>]:: List the stash entries that you currently have. Each 'stash entry' is listed with its name (e.g. `stash@{0}` is the latest entry, `stash@{1}` is @@ -106,16 +83,18 @@ stash@{1}: On master: 9cc0589... Add git-stash The command takes options applicable to the 'git log' command to control what is shown and how. See linkgit:git-log[1]. -show [<options>] [<stash>]:: +show [-u|--include-untracked|--only-untracked] [<diff-options>] [<stash>]:: Show the changes recorded in the stash entry as a diff between the stashed contents and the commit back when the stash entry was first - created. When no `<stash>` is given, it shows the latest one. + created. By default, the command shows the diffstat, but it will accept any format known to 'git diff' (e.g., `git stash show -p stash@{1}` to view the second most recent entry in patch form). - You can use stash.showStat and/or stash.showPatch config variables - to change the default behavior. + If no `<diff-option>` is provided, the default behavior will be given + by the `stash.showStat`, and `stash.showPatch` config variables. You + can also use `stash.showIncludeUntracked` to set whether + `--include-untracked` is enabled by default. pop [--index] [-q|--quiet] [<stash>]:: @@ -127,14 +106,6 @@ pop [--index] [-q|--quiet] [<stash>]:: Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call `git stash drop` manually afterwards. -+ -If the `--index` option is used, then tries to reinstate not only the working -tree's changes, but also the index's ones. However, this can fail, when you -have conflicts (which are stored in the index, where you therefore can no -longer apply the changes as they were originally). -+ -When no `<stash>` is given, `stash@{0}` is assumed, otherwise `<stash>` must -be a reference of the form `stash@{<revision>}`. apply [--index] [-q|--quiet] [<stash>]:: @@ -148,8 +119,7 @@ branch <branchname> [<stash>]:: the commit at which the `<stash>` was originally created, applies the changes recorded in `<stash>` to the new working tree and index. If that succeeds, and `<stash>` is a reference of the form - `stash@{<revision>}`, it then drops the `<stash>`. When no `<stash>` - is given, applies the latest one. + `stash@{<revision>}`, it then drops the `<stash>`. + This is useful if the branch on which you ran `git stash push` has changed enough that `git stash apply` fails due to conflicts. Since @@ -165,9 +135,6 @@ clear:: drop [-q|--quiet] [<stash>]:: Remove a single stash entry from the list of stash entries. - When no `<stash>` is given, it removes the latest one. - i.e. `stash@{0}`, otherwise `<stash>` must be a valid stash - log reference of the form `stash@{<revision>}`. create:: @@ -184,6 +151,106 @@ store:: reflog. This is intended to be useful for scripts. It is probably not the command you want to use; see "push" above. +OPTIONS +------- +-a:: +--all:: + This option is only valid for `push` and `save` commands. ++ +All ignored and untracked files are also stashed and then cleaned +up with `git clean`. + +-u:: +--include-untracked:: +--no-include-untracked:: + When used with the `push` and `save` commands, + all untracked files are also stashed and then cleaned up with + `git clean`. ++ +When used with the `show` command, show the untracked files in the stash +entry as part of the diff. + +--only-untracked:: + This option is only valid for the `show` command. ++ +Show only the untracked files in the stash entry as part of the diff. + +--index:: + This option is only valid for `pop` and `apply` commands. ++ +Tries to reinstate not only the working tree's changes, but also +the index's ones. However, this can fail, when you have conflicts +(which are stored in the index, where you therefore can no longer +apply the changes as they were originally). + +-k:: +--keep-index:: +--no-keep-index:: + This option is only valid for `push` and `save` commands. ++ +All changes already added to the index are left intact. + +-p:: +--patch:: + This option is only valid for `push` and `save` commands. ++ +Interactively select hunks from the diff between HEAD and the +working tree to be stashed. The stash entry is constructed such +that its index state is the same as the index state of your +repository, and its worktree contains only the changes you selected +interactively. The selected changes are then rolled back from your +worktree. See the ``Interactive Mode'' section of linkgit:git-add[1] +to learn how to operate the `--patch` mode. ++ +The `--patch` option implies `--keep-index`. You can use +`--no-keep-index` to override this. + +--pathspec-from-file=<file>:: + This option is only valid for `push` command. ++ +Pathspec is passed in `<file>` instead of commandline args. If +`<file>` is exactly `-` then standard input is used. Pathspec +elements are separated by LF or CR/LF. Pathspec elements can be +quoted as explained for the configuration variable `core.quotePath` +(see linkgit:git-config[1]). See also `--pathspec-file-nul` and +global `--literal-pathspecs`. + +--pathspec-file-nul:: + This option is only valid for `push` command. ++ +Only meaningful with `--pathspec-from-file`. Pathspec elements are +separated with NUL character and all other characters are taken +literally (including newlines and quotes). + +-q:: +--quiet:: + This option is only valid for `apply`, `drop`, `pop`, `push`, + `save`, `store` commands. ++ +Quiet, suppress feedback messages. + +\--:: + This option is only valid for `push` command. ++ +Separates pathspec from options for disambiguation purposes. + +<pathspec>...:: + This option is only valid for `push` command. ++ +The new stash entry records the modified states only for the files +that match the pathspec. The index entries and working tree files +are then rolled back to the state in HEAD only for these files, +too, leaving files that do not match the pathspec intact. ++ +For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. + +<stash>:: + This option is only valid for `apply`, `branch`, `drop`, `pop`, + `show` commands. ++ +A reference of the form `stash@{<revision>}`. When no `<stash>` is +given, the latest stash is assumed (that is, `stash@{0}`). + DISCUSSION ---------- @@ -235,12 +302,12 @@ return to your original branch to make the emergency fix, like this: + ---------------------------------------------------------------- # ... hack hack hack ... -$ git checkout -b my_wip +$ git switch -c my_wip $ git commit -a -m "WIP" -$ git checkout master +$ git switch master $ edit emergency fix $ git commit -a -m "Fix in a hurry" -$ git checkout my_wip +$ git switch my_wip $ git reset --soft HEAD^ # ... continue hacking ... ---------------------------------------------------------------- @@ -293,7 +360,8 @@ SEE ALSO linkgit:git-checkout[1], linkgit:git-commit[1], linkgit:git-reflog[1], -linkgit:git-reset[1] +linkgit:git-reset[1], +linkgit:git-switch[1] GIT --- diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index d4e8f24f0c..83f38e3198 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -59,16 +59,17 @@ This is optional and defaults to the original version 'v1' format. --untracked-files[=<mode>]:: Show untracked files. + +-- The mode parameter is used to specify the handling of untracked files. It is optional: it defaults to 'all', and if specified, it must be stuck to the option (e.g. `-uno`, but not `-u no`). -+ + The possible options are: -+ + - 'no' - Show no untracked files. - 'normal' - Shows untracked files and directories. - 'all' - Also shows individual files in untracked directories. -+ + When `-u` option is not used, untracked files and directories are shown (i.e. the same as specifying `normal`), to help you avoid forgetting to add newly created files. Because it takes extra work @@ -78,9 +79,10 @@ Consider enabling untracked cache and split index if supported (see `git update-index --untracked-cache` and `git update-index --split-index`), Otherwise you can use `no` to have `git status` return more quickly without showing untracked files. -+ + The default can be changed using the status.showUntrackedFiles configuration variable documented in linkgit:git-config[1]. +-- --ignore-submodules[=<when>]:: Ignore changes to submodules when looking for changes. <when> can be @@ -100,11 +102,12 @@ configuration variable documented in linkgit:git-config[1]. --ignored[=<mode>]:: Show ignored files as well. + +-- The mode parameter is used to specify the handling of ignored files. It is optional: it defaults to 'traditional'. -+ + The possible options are: -+ + - 'traditional' - Shows ignored files and directories, unless --untracked-files=all is specified, in which case individual files in ignored directories are @@ -112,12 +115,13 @@ The possible options are: - 'no' - Show no ignored files. - 'matching' - Shows ignored files and directories matching an ignore pattern. -+ + When 'matching' mode is specified, paths that explicitly match an ignored pattern are shown. If a directory matches an ignore pattern, then it is shown, but not paths contained in the ignored directory. If a directory does not match an ignore pattern, but all contents are ignored, then the directory is not shown, but all contents are shown. +-- -z:: Terminate entries with NUL, instead of LF. This implies @@ -126,7 +130,7 @@ ignored, then the directory is not shown, but all contents are shown. --column[=<options>]:: --no-column:: Display untracked files in columns. See configuration variable - column.status for option syntax.`--column` and `--no-column` + `column.status` for option syntax. `--column` and `--no-column` without options are equivalent to 'always' and 'never' respectively. @@ -180,11 +184,26 @@ characters, that field will be quoted in the manner of a C string literal: surrounded by ASCII double quote (34) characters, and with interior special characters backslash-escaped. -For paths with merge conflicts, `X` and `Y` show the modification -states of each side of the merge. For paths that do not have merge -conflicts, `X` shows the status of the index, and `Y` shows the status -of the work tree. For untracked paths, `XY` are `??`. Other status -codes can be interpreted as follows: +There are three different types of states that are shown using this format, and +each one uses the `XY` syntax differently: + +* When a merge is occurring and the merge was successful, or outside of a merge + situation, `X` shows the status of the index and `Y` shows the status of the + working tree. +* When a merge conflict has occurred and has not yet been resolved, `X` and `Y` + show the state introduced by each head of the merge, relative to the common + ancestor. These paths are said to be _unmerged_. +* When a path is untracked, `X` and `Y` are always the same, since they are + unknown to the index. `??` is used for untracked paths. Ignored files are + not listed unless `--ignored` is used; if it is, ignored files are indicated + by `!!`. + +Note that the term _merge_ here also includes rebases using the default +`--merge` strategy, cherry-picks, and anything else using the merge machinery. + +In the following table, these three classes are shown in separate sections, and +these characters are used for `X` and `Y` fields for the first two sections that +show tracked paths: * ' ' = unmodified * 'M' = modified @@ -194,9 +213,6 @@ codes can be interpreted as follows: * 'C' = copied * 'U' = updated but unmerged -Ignored files are not listed, unless `--ignored` option is in effect, -in which case `XY` are `!!`. - .... X Y Meaning ------------------------------------------------- diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 0ed5c24dc1..7e5f995f77 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -16,6 +16,7 @@ SYNOPSIS 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...) 'git submodule' [--quiet] update [<options>] [--] [<path>...] 'git submodule' [--quiet] set-branch [<options>] [--] <path> +'git submodule' [--quiet] set-url [--] <path> <newurl> 'git submodule' [--quiet] summary [<options>] [--] [<path>...] 'git submodule' [--quiet] foreach [--recursive] <command> 'git submodule' [--quiet] sync [--recursive] [--] [<path>...] @@ -80,6 +81,9 @@ status [--cached] [--recursive] [--] [<path>...]:: does not match the SHA-1 found in the index of the containing repository and `U` if the submodule has merge conflicts. + +If `--cached` is specified, this command will instead print the SHA-1 +recorded in the superproject for each submodule. ++ If `--recursive` is specified, this command will recurse into nested submodules, and show their status as well. + @@ -129,11 +133,12 @@ If you really want to remove a submodule from the repository and commit that use linkgit:git-rm[1] instead. See linkgit:gitsubmodules[7] for removal options. -update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...]:: +update [--init] [--remote] [-N|--no-fetch] [--[no-]recommend-shallow] [-f|--force] [--checkout|--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--[no-]single-branch] [--] [<path>...]:: + -- Update the registered submodules to match what the superproject -expects by cloning missing submodules and updating the working tree of +expects by cloning missing submodules, fetching missing commits +in submodules and updating the working tree of the submodules. The "updating" can be done in several ways depending on command line options and the value of `submodule.<name>.update` configuration variable. The command line option takes precedence over @@ -173,11 +178,17 @@ submodule with the `--init` option. If `--recursive` is specified, this command will recurse into the registered submodules, and update any nested submodules within. -- -set-branch ((-d|--default)|(-b|--branch <branch>)) [--] <path>:: +set-branch (-b|--branch) <branch> [--] <path>:: +set-branch (-d|--default) [--] <path>:: Sets the default remote tracking branch for the submodule. The `--branch` option allows the remote branch to be specified. The `--default` option removes the submodule.<name>.branch configuration - key, which causes the tracking branch to default to 'master'. + key, which causes the tracking branch to default to the remote 'HEAD'. + +set-url [--] <path> <newurl>:: + Sets the URL of the specified submodule to <newurl>. Then, it will + automatically synchronize the submodule's new remote URL + configuration. summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]:: Show commit summary between the given commit (defaults to HEAD) and @@ -218,7 +229,7 @@ As an example, the command below will show the path and currently checked out commit for each submodule: + -------------- -git submodule foreach 'echo $path `git rev-parse HEAD`' +git submodule foreach 'echo $sm_path `git rev-parse HEAD`' -------------- sync [--recursive] [--] [<path>...]:: @@ -237,7 +248,7 @@ registered submodules, and sync any nested submodules within. absorbgitdirs:: If a git directory of a submodule is inside the submodule, - move the git directory of the submodule into its superprojects + move the git directory of the submodule into its superproject's `$GIT_DIR/modules` path and then connect the git directory and its working directory by setting the `core.worktree` and adding a .git file pointing to the git directory embedded in the @@ -273,7 +284,7 @@ OPTIONS `.gitmodules` for `update --remote`. A special value of `.` is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the - option is not specified, it defaults to 'master'. + option is not specified, it defaults to the remote 'HEAD'. -f:: --force:: @@ -311,10 +322,10 @@ OPTIONS the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch. The remote used is branch's remote (`branch.<name>.remote`), defaulting to `origin`. - The remote branch used defaults to `master`, but the branch name may - be overridden by setting the `submodule.<name>.branch` option in - either `.gitmodules` or `.git/config` (with `.git/config` taking - precedence). + The remote branch used defaults to the remote `HEAD`, but the branch + name may be overridden by setting the `submodule.<name>.branch` + option in either `.gitmodules` or `.git/config` (with `.git/config` + taking precedence). + This works for any of the supported update procedures (`--checkout`, `--rebase`, etc.). The only change is the source of the target SHA-1. @@ -419,6 +430,10 @@ options carefully. Clone new submodules in parallel with as many jobs. Defaults to the `submodule.fetchJobs` option. +--[no-]single-branch:: + This option is only valid for the update command. + Clone only one branch during update: HEAD or one specified by --branch. + <path>...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 30711625fd..d5776ffcfd 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -677,7 +677,8 @@ config key: svn.authorsProg -s<strategy>:: --strategy=<strategy>:: -p:: ---preserve-merges:: +--rebase-merges:: +--preserve-merges (DEPRECATED):: These are only used with the 'dcommit' and 'rebase' commands. + Passed directly to 'git rebase' when using 'dcommit' if a @@ -700,7 +701,7 @@ creating the branch or tag. --use-log-author:: When retrieving svn commits into Git (as part of 'fetch', 'rebase', or - 'dcommit' operations), look for the first `From:` or `Signed-off-by:` line + 'dcommit' operations), look for the first `From:` line or `Signed-off-by` trailer in the log message and use that as the author string. + [verse] @@ -709,7 +710,7 @@ config key: svn.useLogAuthor --add-author-from:: When committing to svn from Git (as part of 'set-tree' or 'dcommit' operations), if the existing log message doesn't already have a - `From:` or `Signed-off-by:` line, append a `From:` line based on the + `From:` or `Signed-off-by` trailer, append a `From:` line based on the Git commit's author string. If you use this, then `--use-log-author` will retrieve a valid author string for all commits. + @@ -769,11 +770,11 @@ option for (hopefully) obvious reasons. + This option is NOT recommended as it makes it difficult to track down old references to SVN revision numbers in existing documentation, bug -reports and archives. If you plan to eventually migrate from SVN to Git -and are certain about dropping SVN history, consider -linkgit:git-filter-branch[1] instead. filter-branch also allows -reformatting of metadata for ease-of-reading and rewriting authorship -info for non-"svn.authorsFile" users. +reports, and archives. If you plan to eventually migrate from SVN to +Git and are certain about dropping SVN history, consider +https://github.com/newren/git-filter-repo[git-filter-repo] instead. +filter-repo also allows reformatting of metadata for ease-of-reading +and rewriting authorship info for non-"svn.authorsFile" users. svn.useSvmProps:: svn-remote.<name>.useSvmProps:: @@ -1060,25 +1061,6 @@ with different name spaces. For example: branches = stable/*:refs/remotes/svn/stable/* branches = debug/*:refs/remotes/svn/debug/* -BUGS ----- - -We ignore all SVN properties except svn:executable. Any unhandled -properties are logged to $GIT_DIR/svn/<refname>/unhandled.log - -Renamed and copied directories are not detected by Git and hence not -tracked when committing to SVN. I do not plan on adding support for -this as it's quite difficult and time-consuming to get working for all -the possible corner cases (Git doesn't do it, either). Committing -renamed and copied files is fully supported if they're similar enough -for Git to detect them. - -In SVN, it is possible (though discouraged) to commit changes to a tag -(because a tag is just a directory copy, thus technically the same as a -branch). When cloning an SVN repository, 'git svn' cannot know if such a -commit to a tag will happen in the future. Thus it acts conservatively -and imports all SVN tags as branches, prefixing the tag name with 'tags/'. - CONFIGURATION ------------- @@ -1165,6 +1147,25 @@ $GIT_DIR/svn/\**/.rev_map.*:: if it is missing or not up to date. 'git svn reset' automatically rewinds it. +BUGS +---- + +We ignore all SVN properties except svn:executable. Any unhandled +properties are logged to $GIT_DIR/svn/<refname>/unhandled.log + +Renamed and copied directories are not detected by Git and hence not +tracked when committing to SVN. I do not plan on adding support for +this as it's quite difficult and time-consuming to get working for all +the possible corner cases (Git doesn't do it, either). Committing +renamed and copied files is fully supported if they're similar enough +for Git to detect them. + +In SVN, it is possible (though discouraged) to commit changes to a tag +(because a tag is just a directory copy, thus technically the same as a +branch). When cloning an SVN repository, 'git svn' cannot know if such a +commit to a tag will happen in the future. Thus it acts conservatively +and imports all SVN tags as branches, prefixing the tag name with 'tags/'. + SEE ALSO -------- linkgit:git-rebase[1] diff --git a/Documentation/git-switch.txt b/Documentation/git-switch.txt new file mode 100644 index 0000000000..5c438cd505 --- /dev/null +++ b/Documentation/git-switch.txt @@ -0,0 +1,276 @@ +git-switch(1) +============= + +NAME +---- +git-switch - Switch branches + +SYNOPSIS +-------- +[verse] +'git switch' [<options>] [--no-guess] <branch> +'git switch' [<options>] --detach [<start-point>] +'git switch' [<options>] (-c|-C) <new-branch> [<start-point>] +'git switch' [<options>] --orphan <new-branch> + +DESCRIPTION +----------- +Switch to a specified branch. The working tree and the index are +updated to match the branch. All new commits will be added to the tip +of this branch. + +Optionally a new branch could be created with either `-c`, `-C`, +automatically from a remote branch of same name (see `--guess`), or +detach the working tree from any branch with `--detach`, along with +switching. + +Switching branches does not require a clean index and working tree +(i.e. no differences compared to `HEAD`). The operation is aborted +however if the operation leads to loss of local changes, unless told +otherwise with `--discard-changes` or `--merge`. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +OPTIONS +------- +<branch>:: + Branch to switch to. + +<new-branch>:: + Name for the new branch. + +<start-point>:: + The starting point for the new branch. Specifying a + `<start-point>` allows you to create a branch based on some + other point in history than where HEAD currently points. (Or, + in the case of `--detach`, allows you to inspect and detach + from some other point.) ++ +You can use the `@{-N}` syntax to refer to the N-th last +branch/commit switched to using "git switch" or "git checkout" +operation. You may also specify `-` which is synonymous to `@{-1}`. +This is often used to switch quickly between two branches, or to undo +a branch switch by mistake. ++ +As a special case, you may use `A...B` as a shortcut for the merge +base of `A` and `B` if there is exactly one merge base. You can leave +out at most one of `A` and `B`, in which case it defaults to `HEAD`. + +-c <new-branch>:: +--create <new-branch>:: + Create a new branch named `<new-branch>` starting at + `<start-point>` before switching to the branch. This is a + convenient shortcut for: ++ +------------ +$ git branch <new-branch> +$ git switch <new-branch> +------------ + +-C <new-branch>:: +--force-create <new-branch>:: + Similar to `--create` except that if `<new-branch>` already + exists, it will be reset to `<start-point>`. This is a + convenient shortcut for: ++ +------------ +$ git branch -f <new-branch> +$ git switch <new-branch> +------------ + +-d:: +--detach:: + Switch to a commit for inspection and discardable + experiments. See the "DETACHED HEAD" section in + linkgit:git-checkout[1] for details. + +--guess:: +--no-guess:: + If `<branch>` is not found but there does exist a tracking + branch in exactly one remote (call it `<remote>`) with a + matching name, treat as equivalent to ++ +------------ +$ git switch -c <branch> --track <remote>/<branch> +------------ ++ +If the branch exists in multiple remotes and one of them is named by +the `checkout.defaultRemote` configuration variable, we'll use that +one for the purposes of disambiguation, even if the `<branch>` isn't +unique across all remotes. Set it to e.g. `checkout.defaultRemote=origin` +to always checkout remote branches from there if `<branch>` is +ambiguous but exists on the 'origin' remote. See also +`checkout.defaultRemote` in linkgit:git-config[1]. ++ +`--guess` is the default behavior. Use `--no-guess` to disable it. ++ +The default behavior can be set via the `checkout.guess` configuration +variable. + +-f:: +--force:: + An alias for `--discard-changes`. + +--discard-changes:: + Proceed even if the index or the working tree differs from + `HEAD`. Both the index and working tree are restored to match + the switching target. If `--recurse-submodules` is specified, + submodule content is also restored to match the switching + target. This is used to throw away local changes. + +-m:: +--merge:: + If you have local modifications to one or more files that are + different between the current branch and the branch to which + you are switching, the command refuses to switch branches in + order to preserve your modifications in context. However, + with this option, a three-way merge between the current + branch, your working tree contents, and the new branch is + done, and you will be on the new branch. ++ +When a merge conflict happens, the index entries for conflicting +paths are left unmerged, and you need to resolve the conflicts +and mark the resolved paths with `git add` (or `git rm` if the merge +should result in deletion of the path). + +--conflict=<style>:: + The same as `--merge` option above, but changes the way the + conflicting hunks are presented, overriding the + `merge.conflictStyle` configuration variable. Possible values are + "merge" (default) and "diff3" (in addition to what is shown by + "merge" style, shows the original contents). + +-q:: +--quiet:: + Quiet, suppress feedback messages. + +--progress:: +--no-progress:: + Progress status is reported on the standard error stream + by default when it is attached to a terminal, unless `--quiet` + is specified. This flag enables progress reporting even if not + attached to a terminal, regardless of `--quiet`. + +-t:: +--track:: + When creating a new branch, set up "upstream" configuration. + `-c` is implied. See `--track` in linkgit:git-branch[1] for + details. ++ +If no `-c` option is given, the name of the new branch will be derived +from the remote-tracking branch, by looking at the local part of the +refspec configured for the corresponding remote, and then stripping +the initial part up to the "*". This would tell us to use `hack` as +the local branch when branching off of `origin/hack` (or +`remotes/origin/hack`, or even `refs/remotes/origin/hack`). If the +given name has no slash, or the above guessing results in an empty +name, the guessing is aborted. You can explicitly give a name with +`-c` in such a case. + +--no-track:: + Do not set up "upstream" configuration, even if the + `branch.autoSetupMerge` configuration variable is true. + +--orphan <new-branch>:: + Create a new 'orphan' branch, named `<new-branch>`. All + tracked files are removed. + +--ignore-other-worktrees:: + `git switch` refuses when the wanted ref is already + checked out by another worktree. This option makes it check + the ref out anyway. In other words, the ref can be held by + more than one worktree. + +--recurse-submodules:: +--no-recurse-submodules:: + Using `--recurse-submodules` will update the content of all + active submodules according to the commit recorded in the + superproject. If nothing (or `--no-recurse-submodules`) is + used, submodules working trees will not be updated. Just + like linkgit:git-submodule[1], this will detach `HEAD` of the + submodules. + +EXAMPLES +-------- + +The following command switches to the "master" branch: + +------------ +$ git switch master +------------ + +After working in the wrong branch, switching to the correct branch +would be done using: + +------------ +$ git switch mytopic +------------ + +However, your "wrong" branch and correct "mytopic" branch may differ +in files that you have modified locally, in which case the above +switch would fail like this: + +------------ +$ git switch mytopic +error: You have local changes to 'frotz'; not switching branches. +------------ + +You can give the `-m` flag to the command, which would try a three-way +merge: + +------------ +$ git switch -m mytopic +Auto-merging frotz +------------ + +After this three-way merge, the local modifications are _not_ +registered in your index file, so `git diff` would show you what +changes you made since the tip of the new branch. + +To switch back to the previous branch before we switched to mytopic +(i.e. "master" branch): + +------------ +$ git switch - +------------ + +You can grow a new branch from any commit. For example, switch to +"HEAD~3" and create branch "fixup": + +------------ +$ git switch -c fixup HEAD~3 +Switched to a new branch 'fixup' +------------ + +If you want to start a new branch from a remote branch of the same +name: + +------------ +$ git switch new-topic +Branch 'new-topic' set up to track remote branch 'new-topic' from 'origin' +Switched to a new branch 'new-topic' +------------ + +To check out commit `HEAD~3` for temporary inspection or experiment +without creating a new branch: + +------------ +$ git switch --detach HEAD~3 +HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits' +------------ + +If it turns out whatever you have done is worth keeping, you can +always create a new name for it (without switching away): + +------------ +$ git switch -c good-surprises +------------ + +SEE ALSO +-------- +linkgit:git-checkout[1], +linkgit:git-branch[1] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt index a74e7b926d..31a97a1b6c 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.txt @@ -15,7 +15,7 @@ SYNOPSIS 'git tag' [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>] [--points-at <object>] [--column[=<options>] | --no-column] [--create-reflog] [--sort=<key>] [--format=<format>] - [--[no-]merged [<commit>]] [<pattern>...] + [--merged <commit>] [--no-merged <commit>] [<pattern>...] 'git tag' -v [--format=<format>] <tagname>... DESCRIPTION @@ -64,6 +64,13 @@ OPTIONS -s:: --sign:: Make a GPG-signed tag, using the default e-mail address's key. + The default behavior of tag GPG-signing is controlled by `tag.gpgSign` + configuration variable if it exists, or disabled otherwise. + See linkgit:git-config[1]. + +--no-sign:: + Override `tag.gpgSign` configuration variable that is + set to force each and every tag to be signed. -u <keyid>:: --local-user=<keyid>:: @@ -127,7 +134,7 @@ options for details. --column[=<options>]:: --no-column:: Display tag listing in columns. See configuration variable - column.tag for option syntax.`--column` and `--no-column` + `column.tag` for option syntax. `--column` and `--no-column` without options are equivalent to 'always' and 'never' respectively. + This option is only applicable when listing tags without annotation lines. @@ -142,11 +149,11 @@ This option is only applicable when listing tags without annotation lines. --merged [<commit>]:: Only list tags whose commits are reachable from the specified - commit (`HEAD` if not specified), incompatible with `--no-merged`. + commit (`HEAD` if not specified). --no-merged [<commit>]:: Only list tags whose commits are not reachable from the specified - commit (`HEAD` if not specified), incompatible with `--merged`. + commit (`HEAD` if not specified). --points-at <object>:: Only list tags of the given object (HEAD if not @@ -370,6 +377,11 @@ $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1 include::date-formats.txt[] +NOTES +----- + +include::ref-reachability-filters.txt[] + SEE ALSO -------- linkgit:git-check-ref-format[1]. diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 1c4d146a41..2853f168d9 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -16,6 +16,7 @@ SYNOPSIS [--chmod=(+|-)x] [--[no-]assume-unchanged] [--[no-]skip-worktree] + [--[no-]ignore-skip-worktree-entries] [--[no-]fsmonitor-valid] [--ignore-submodules] [--[no-]split-index] @@ -29,9 +30,8 @@ SYNOPSIS DESCRIPTION ----------- -Modifies the index or directory cache. Each file mentioned is updated -into the index and any 'unmerged' or 'needs updating' state is -cleared. +Modifies the index. Each file mentioned is updated into the index and +any 'unmerged' or 'needs updating' state is cleared. See also linkgit:git-add[1] for a more user-friendly way to do some of the most common operations on the index. @@ -113,6 +113,11 @@ you will need to handle the situation manually. set and unset the "skip-worktree" bit for the paths. See section "Skip-worktree bit" below for more information. + +--[no-]ignore-skip-worktree-entries:: + Do not remove skip-worktree (AKA "index-only") entries even when + the `--remove` option was specified. + --[no-]fsmonitor-valid:: When one of these flags is specified, the object name recorded for the paths are not updated. Instead, these options @@ -426,7 +431,7 @@ specified by the splitIndex.sharedIndexExpire config variable (see linkgit:git-config[1]). To avoid deleting a shared index file that is still used, its -modification time is updated to the current time everytime a new split +modification time is updated to the current time every time a new split index based on the shared index file is either created or read from. UNTRACKED CACHE @@ -543,6 +548,22 @@ The untracked cache extension can be enabled by the `core.untrackedCache` configuration variable (see linkgit:git-config[1]). +NOTES +----- + +Users often try to use the assume-unchanged and skip-worktree bits +to tell Git to ignore changes to files that are tracked. This does not +work as expected, since Git may still check working tree files against +the index when performing certain operations. In general, Git does not +provide a way to ignore changes to tracked files, so alternate solutions +are recommended. + +For example, if the file you want to change is some sort of config file, +the repository can include a sample config file that can then be copied +into the ignored name and modified. The repository can even include a +script to treat the sample file as a template, modifying and copying it +automatically. + SEE ALSO -------- linkgit:git-config[1], diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.txt index 9671423117..48b6683071 100644 --- a/Documentation/git-update-ref.txt +++ b/Documentation/git-update-ref.txt @@ -66,6 +66,10 @@ performs all modifications together. Specify commands of the form: delete SP <ref> [SP <oldvalue>] LF verify SP <ref> [SP <oldvalue>] LF option SP <opt> LF + start LF + prepare LF + commit LF + abort LF With `--create-reflog`, update-ref will create a reflog for each ref even if one would not ordinarily be created. @@ -83,6 +87,10 @@ quoting: delete SP <ref> NUL [<oldvalue>] NUL verify SP <ref> NUL [<oldvalue>] NUL option SP <opt> NUL + start NUL + prepare NUL + commit NUL + abort NUL In this format, use 40 "0" to specify a zero value, and use the empty string to specify a missing value. @@ -107,13 +115,32 @@ delete:: verify:: Verify <ref> against <oldvalue> but do not change it. If - <oldvalue> zero or missing, the ref must not exist. + <oldvalue> is zero or missing, the ref must not exist. option:: Modify behavior of the next command naming a <ref>. The only valid option is `no-deref` to avoid dereferencing a symbolic ref. +start:: + Start a transaction. In contrast to a non-transactional session, a + transaction will automatically abort if the session ends without an + explicit commit. This command may create a new empty transaction when + the current one has been committed or aborted already. + +prepare:: + Prepare to commit the transaction. This will create lock files for all + queued reference updates. If one reference could not be locked, the + transaction will be aborted. + +commit:: + Commit all reference updates queued for the transaction, ending the + transaction. + +abort:: + Abort the transaction, releasing all locks if the transaction is in + prepared state. + If all <ref>s can be locked with matching <oldvalue>s simultaneously, all modifications are performed. Otherwise, no modifications are performed. Note that while each individual @@ -122,12 +149,13 @@ still see a subset of the modifications. LOGGING UPDATES --------------- -If config parameter "core.logAllRefUpdates" is true and the ref is one under -"refs/heads/", "refs/remotes/", "refs/notes/", or the symbolic ref HEAD; or -the file "$GIT_DIR/logs/<ref>" exists then `git update-ref` will append -a line to the log file "$GIT_DIR/logs/<ref>" (dereferencing all -symbolic refs before creating the log name) describing the change -in ref value. Log lines are formatted as: +If config parameter "core.logAllRefUpdates" is true and the ref is one +under "refs/heads/", "refs/remotes/", "refs/notes/", or a pseudoref +like HEAD or ORIG_HEAD; or the file "$GIT_DIR/logs/<ref>" exists then +`git update-ref` will append a line to the log file +"$GIT_DIR/logs/<ref>" (dereferencing all symbolic refs before creating +the log name) describing the change in ref value. Log lines are +formatted as: oldsha1 SP newsha1 SP committer LF diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.txt index bd0e36492f..969bb2e15f 100644 --- a/Documentation/git-update-server-info.txt +++ b/Documentation/git-update-server-info.txt @@ -9,7 +9,7 @@ git-update-server-info - Update auxiliary info file to help dumb servers SYNOPSIS -------- [verse] -'git update-server-info' [--force] +'git update-server-info' DESCRIPTION ----------- @@ -19,15 +19,6 @@ $GIT_OBJECT_DIRECTORY/info directories to help clients discover what references and packs the server has. This command generates such auxiliary files. - -OPTIONS -------- - --f:: ---force:: - Update the info files from scratch. - - OUTPUT ------ diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt index 85d92c9761..8a7cbdd19c 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -9,12 +9,13 @@ git-worktree - Manage multiple working trees SYNOPSIS -------- [verse] -'git worktree add' [-f] [--detach] [--checkout] [--lock] [-b <new-branch>] <path> [<commit-ish>] +'git worktree add' [-f] [--detach] [--checkout] [--lock [--reason <string>]] [-b <new-branch>] <path> [<commit-ish>] 'git worktree list' [--porcelain] 'git worktree lock' [--reason <string>] <worktree> 'git worktree move' <worktree> <new-path> 'git worktree prune' [-n] [-v] [--expire <expire>] 'git worktree remove' [-f] <worktree> +'git worktree repair' [<path>...] 'git worktree unlock' <worktree> DESCRIPTION @@ -25,11 +26,24 @@ Manage multiple working trees attached to the same repository. A git repository can support multiple working trees, allowing you to check out more than one branch at a time. With `git worktree add` a new working tree is associated with the repository. This new working tree is called a -"linked working tree" as opposed to the "main working tree" prepared by "git -init" or "git clone". A repository has one main working tree (if it's not a +"linked working tree" as opposed to the "main working tree" prepared by +linkgit:git-init[1] or linkgit:git-clone[1]. +A repository has one main working tree (if it's not a bare repository) and zero or more linked working trees. When you are done with a linked working tree, remove it with `git worktree remove`. +In its simplest form, `git worktree add <path>` automatically creates a +new branch whose name is the final component of `<path>`, which is +convenient if you plan to work on a new topic. For instance, `git +worktree add ../hotfix` creates new branch `hotfix` and checks it out at +path `../hotfix`. To instead work on an existing branch in a new working +tree, use `git worktree add <path> <branch>`. On the other hand, if you +just plan to make some experimental changes or do testing without +disturbing existing development, it is often convenient to create a +'throwaway' working tree not associated with any branch. For instance, +`git worktree add -d <path>` creates a new working tree with a detached +`HEAD` at the same commit as the current branch. + If a working tree is deleted without using `git worktree remove`, then its associated administrative files, which reside in the repository (see "DETAILS" below), will eventually be removed automatically (see @@ -48,10 +62,10 @@ add <path> [<commit-ish>]:: Create `<path>` and checkout `<commit-ish>` into it. The new working directory is linked to the current repository, sharing everything except working -directory specific files such as HEAD, index, etc. `-` may also be -specified as `<commit-ish>`; it is synonymous with `@{-1}`. +directory specific files such as `HEAD`, `index`, etc. As a convenience, +`<commit-ish>` may be a bare "`-`", which is synonymous with `@{-1}`. + -If <commit-ish> is a branch name (call it `<branch>`) and is not found, +If `<commit-ish>` is a branch name (call it `<branch>`) and is not found, and neither `-b` nor `-B` nor `--detach` are used, but there does exist a tracking branch in exactly one remote (call it `<remote>`) with a matching name, treat as equivalent to: @@ -66,24 +80,26 @@ one for the purposes of disambiguation, even if the `<branch>` isn't unique across all remotes. Set it to e.g. `checkout.defaultRemote=origin` to always checkout remote branches from there if `<branch>` is ambiguous but exists on the -'origin' remote. See also `checkout.defaultRemote` in +`origin` remote. See also `checkout.defaultRemote` in linkgit:git-config[1]. + If `<commit-ish>` is omitted and neither `-b` nor `-B` nor `--detach` used, -then, as a convenience, the new worktree is associated with a branch +then, as a convenience, the new working tree is associated with a branch (call it `<branch>`) named after `$(basename <path>)`. If `<branch>` -doesn't exist, a new branch based on HEAD is automatically created as +doesn't exist, a new branch based on `HEAD` is automatically created as if `-b <branch>` was given. If `<branch>` does exist, it will be -checked out in the new worktree, if it's not checked out anywhere -else, otherwise the command will refuse to create the worktree (unless +checked out in the new working tree, if it's not checked out anywhere +else, otherwise the command will refuse to create the working tree (unless `--force` is used). list:: -List details of each worktree. The main worktree is listed first, followed by -each of the linked worktrees. The output details include if the worktree is -bare, the revision currently checked out, and the branch currently checked out -(or 'detached HEAD' if none). +List details of each working tree. The main working tree is listed first, +followed by each of the linked working trees. The output details include +whether the working tree is bare, the revision currently checked out, the +branch currently checked out (or "detached HEAD" if none), "locked" if +the worktree is locked, "prunable" if the worktree can be pruned by `prune` +command. lock:: @@ -96,11 +112,14 @@ with `--reason`. move:: Move a working tree to a new location. Note that the main working tree -or linked working trees containing submodules cannot be moved. +or linked working trees containing submodules cannot be moved with this +command. (The `git worktree repair` command, however, can reestablish +the connection with linked working trees if you move the main working +tree manually.) prune:: -Prune working tree information in $GIT_DIR/worktrees. +Prune working tree information in `$GIT_DIR/worktrees`. remove:: @@ -109,6 +128,28 @@ and no modification in tracked files) can be removed. Unclean working trees or ones with submodules can be removed with `--force`. The main working tree cannot be removed. +repair [<path>...]:: + +Repair working tree administrative files, if possible, if they have +become corrupted or outdated due to external factors. ++ +For instance, if the main working tree (or bare repository) is moved, +linked working trees will be unable to locate it. Running `repair` in +the main working tree will reestablish the connection from linked +working trees back to the main working tree. ++ +Similarly, if a linked working tree is moved without using `git worktree +move`, the main working tree (or bare repository) will be unable to +locate it. Running `repair` within the recently-moved working tree will +reestablish the connection. If multiple linked working trees are moved, +running `repair` from any working tree with each tree's new `<path>` as +an argument, will reestablish the connection to all the specified paths. ++ +If both the main working tree and linked working trees have been moved +manually, then running `repair` in the main working tree and specifying the +new `<path>` of each linked working tree will reestablish all connections +in both directions. + unlock:: Unlock a working tree, allowing it to be pruned, moved or deleted. @@ -126,7 +167,9 @@ OPTIONS locked working tree path, specify `--force` twice. + `move` refuses to move a locked working tree unless `--force` is specified -twice. +twice. If the destination is already assigned to some other working tree but is +missing (for instance, if `<new-path>` was deleted manually), then `--force` +allows the move to proceed; use `--force` twice if the destination is locked. + `remove` refuses to remove an unclean working tree unless `--force` is used. To remove a locked working tree, specify `--force` twice. @@ -135,13 +178,14 @@ To remove a locked working tree, specify `--force` twice. -B <new-branch>:: With `add`, create a new branch named `<new-branch>` starting at `<commit-ish>`, and check out `<new-branch>` into the new working tree. - If `<commit-ish>` is omitted, it defaults to HEAD. + If `<commit-ish>` is omitted, it defaults to `HEAD`. By default, `-b` refuses to create a new branch if it already exists. `-B` overrides this safeguard, resetting `<new-branch>` to `<commit-ish>`. +-d:: --detach:: - With `add`, detach HEAD in the new working tree. See "DETACHED HEAD" + With `add`, detach `HEAD` in the new working tree. See "DETACHED HEAD" in linkgit:git-checkout[1]. --[no-]checkout:: @@ -152,7 +196,7 @@ To remove a locked working tree, specify `--force` twice. --[no-]guess-remote:: With `worktree add <path>`, without `<commit-ish>`, instead - of creating a new branch from HEAD, if there exists a tracking + of creating a new branch from `HEAD`, if there exists a tracking branch in exactly one remote matching the basename of `<path>`, base the new branch on the remote-tracking branch, and mark the remote-tracking branch as "upstream" from the new branch. @@ -164,12 +208,12 @@ This can also be set up as the default behaviour by using the When creating a new branch, if `<commit-ish>` is a branch, mark it as "upstream" from the new branch. This is the default if `<commit-ish>` is a remote-tracking branch. See - "--track" in linkgit:git-branch[1] for details. + `--track` in linkgit:git-branch[1] for details. --lock:: Keep the working tree locked after creation. This is the equivalent of `git worktree lock` after `git worktree add`, - but without race condition. + but without a race condition. -n:: --dry-run:: @@ -183,65 +227,70 @@ This can also be set up as the default behaviour by using the -q:: --quiet:: - With 'add', suppress feedback messages. + With `add`, suppress feedback messages. -v:: --verbose:: With `prune`, report all removals. ++ +With `list`, output additional information about worktrees (see below). --expire <time>:: - With `prune`, only expire unused working trees older than <time>. + With `prune`, only expire unused working trees older than `<time>`. ++ +With `list`, annotate missing working trees as prunable if they are +older than `<time>`. --reason <string>:: - With `lock`, an explanation why the working tree is locked. + With `lock` or with `add --lock`, an explanation why the working tree is locked. <worktree>:: Working trees can be identified by path, either relative or absolute. + If the last path components in the working tree's path is unique among -working trees, it can be used to identify worktrees. For example if -you only have two working trees, at "/abc/def/ghi" and "/abc/def/ggg", -then "ghi" or "def/ghi" is enough to point to the former working tree. +working trees, it can be used to identify a working tree. For example if +you only have two working trees, at `/abc/def/ghi` and `/abc/def/ggg`, +then `ghi` or `def/ghi` is enough to point to the former working tree. REFS ---- In multiple working trees, some refs may be shared between all working -trees, some refs are local. One example is HEAD is different for all -working trees. This section is about the sharing rules and how to access +trees and some refs are local. One example is `HEAD` which is different for each +working tree. This section is about the sharing rules and how to access refs of one working tree from another. In general, all pseudo refs are per working tree and all refs starting -with "refs/" are shared. Pseudo refs are ones like HEAD which are -directly under GIT_DIR instead of inside GIT_DIR/refs. There is one -exception to this: refs inside refs/bisect and refs/worktree is not +with `refs/` are shared. Pseudo refs are ones like `HEAD` which are +directly under `$GIT_DIR` instead of inside `$GIT_DIR/refs`. There are +exceptions, however: refs inside `refs/bisect` and `refs/worktree` are not shared. Refs that are per working tree can still be accessed from another -working tree via two special paths, main-worktree and worktrees. The -former gives access to per-worktree refs of the main working tree, +working tree via two special paths, `main-worktree` and `worktrees`. The +former gives access to per-working tree refs of the main working tree, while the latter to all linked working trees. -For example, main-worktree/HEAD or main-worktree/refs/bisect/good -resolve to the same value as the main working tree's HEAD and -refs/bisect/good respectively. Similarly, worktrees/foo/HEAD or -worktrees/bar/refs/bisect/bad are the same as -GIT_COMMON_DIR/worktrees/foo/HEAD and -GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad. +For example, `main-worktree/HEAD` or `main-worktree/refs/bisect/good` +resolve to the same value as the main working tree's `HEAD` and +`refs/bisect/good` respectively. Similarly, `worktrees/foo/HEAD` or +`worktrees/bar/refs/bisect/bad` are the same as +`$GIT_COMMON_DIR/worktrees/foo/HEAD` and +`$GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad`. -To access refs, it's best not to look inside GIT_DIR directly. Instead +To access refs, it's best not to look inside `$GIT_DIR` directly. Instead use commands such as linkgit:git-rev-parse[1] or linkgit:git-update-ref[1] which will handle refs correctly. CONFIGURATION FILE ------------------ -By default, the repository "config" file is shared across all working +By default, the repository `config` file is shared across all working trees. If the config variables `core.bare` or `core.worktree` are already present in the config file, they will be applied to the main working trees only. In order to have configuration specific to working trees, you can turn -on "worktreeConfig" extension, e.g.: +on the `worktreeConfig` extension, e.g.: ------------ $ git config extensions.worktreeConfig true @@ -253,7 +302,7 @@ configuration in this file with `git config --worktree`. Older Git versions will refuse to access repositories with this extension. Note that in this file, the exception for `core.bare` and `core.worktree` -is gone. If you have them in $GIT_DIR/config before, you must move +is gone. If they exist in `$GIT_DIR/config`, you must move them to the `config.worktree` of the main working tree. You may also take this opportunity to review and move other configuration that you do not want to share to all working trees: @@ -266,7 +315,7 @@ do not want to share to all working trees: DETAILS ------- Each linked working tree has a private sub-directory in the repository's -$GIT_DIR/worktrees directory. The private sub-directory's name is usually +`$GIT_DIR/worktrees` directory. The private sub-directory's name is usually the base name of the linked working tree's path, possibly appended with a number to make it unique. For example, when `$GIT_DIR=/path/main/.git` the command `git worktree add /path/other/test-next next` creates the linked @@ -274,51 +323,52 @@ working tree in `/path/other/test-next` and also creates a `$GIT_DIR/worktrees/test-next` directory (or `$GIT_DIR/worktrees/test-next1` if `test-next` is already taken). -Within a linked working tree, $GIT_DIR is set to point to this private +Within a linked working tree, `$GIT_DIR` is set to point to this private directory (e.g. `/path/main/.git/worktrees/test-next` in the example) and -$GIT_COMMON_DIR is set to point back to the main working tree's $GIT_DIR +`$GIT_COMMON_DIR` is set to point back to the main working tree's `$GIT_DIR` (e.g. `/path/main/.git`). These settings are made in a `.git` file located at the top directory of the linked working tree. Path resolution via `git rev-parse --git-path` uses either -$GIT_DIR or $GIT_COMMON_DIR depending on the path. For example, in the +`$GIT_DIR` or `$GIT_COMMON_DIR` depending on the path. For example, in the linked working tree `git rev-parse --git-path HEAD` returns `/path/main/.git/worktrees/test-next/HEAD` (not `/path/other/test-next/.git/HEAD` or `/path/main/.git/HEAD`) while `git rev-parse --git-path refs/heads/master` uses -$GIT_COMMON_DIR and returns `/path/main/.git/refs/heads/master`, -since refs are shared across all working trees, except refs/bisect and -refs/worktree. +`$GIT_COMMON_DIR` and returns `/path/main/.git/refs/heads/master`, +since refs are shared across all working trees, except `refs/bisect` and +`refs/worktree`. See linkgit:gitrepository-layout[5] for more information. The rule of thumb is do not make any assumption about whether a path belongs to -$GIT_DIR or $GIT_COMMON_DIR when you need to directly access something -inside $GIT_DIR. Use `git rev-parse --git-path` to get the final path. +`$GIT_DIR` or `$GIT_COMMON_DIR` when you need to directly access something +inside `$GIT_DIR`. Use `git rev-parse --git-path` to get the final path. -If you manually move a linked working tree, you need to update the 'gitdir' file +If you manually move a linked working tree, you need to update the `gitdir` file in the entry's directory. For example, if a linked working tree is moved to `/newpath/test-next` and its `.git` file points to `/path/main/.git/worktrees/test-next`, then update `/path/main/.git/worktrees/test-next/gitdir` to reference `/newpath/test-next` -instead. +instead. Better yet, run `git worktree repair` to reestablish the connection +automatically. -To prevent a $GIT_DIR/worktrees entry from being pruned (which +To prevent a `$GIT_DIR/worktrees` entry from being pruned (which can be useful in some situations, such as when the entry's working tree is stored on a portable device), use the `git worktree lock` command, which adds a file named -'locked' to the entry's directory. The file contains the reason in +`locked` to the entry's directory. The file contains the reason in plain text. For example, if a linked working tree's `.git` file points to `/path/main/.git/worktrees/test-next` then a file named `/path/main/.git/worktrees/test-next/locked` will prevent the `test-next` entry from being pruned. See linkgit:gitrepository-layout[5] for details. -When extensions.worktreeConfig is enabled, the config file +When `extensions.worktreeConfig` is enabled, the config file `.git/worktrees/<id>/config.worktree` is read after `.git/config` is. LIST OUTPUT FORMAT ------------------ -The worktree list command has two output formats. The default format shows the +The `worktree list` command has two output formats. The default format shows the details on a single line with columns. For example: ------------ @@ -328,13 +378,46 @@ $ git worktree list /path/to/other-linked-worktree 1234abc (detached HEAD) ------------ +The command also shows annotations for each working tree, according to its state. +These annotations are: + + * `locked`, if the working tree is locked. + * `prunable`, if the working tree can be pruned via `git worktree prune`. + +------------ +$ git worktree list +/path/to/linked-worktree abcd1234 [master] +/path/to/locked-worktree acbd5678 (brancha) locked +/path/to/prunable-worktree 5678abc (detached HEAD) prunable +------------ + +For these annotations, a reason might also be available and this can be +seen using the verbose mode. The annotation is then moved to the next line +indented followed by the additional information. + +------------ +$ git worktree list --verbose +/path/to/linked-worktree abcd1234 [master] +/path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked +/path/to/locked-worktree-with-reason 1234abcd (brancha) + locked: working tree path is mounted on a portable device +/path/to/prunable-worktree 5678abc1 (detached HEAD) + prunable: gitdir file points to non-existent location +------------ + +Note that the annotation is moved to the next line if the additional +information is available, otherwise it stays on the same line as the +working tree itself. + Porcelain Format ~~~~~~~~~~~~~~~~ The porcelain format has a line per attribute. Attributes are listed with a -label and value separated by a single space. Boolean attributes (like 'bare' -and 'detached') are listed as a label only, and are only present if and only -if the value is true. The first attribute of a worktree is always `worktree`, -an empty line indicates the end of the record. For example: +label and value separated by a single space. Boolean attributes (like `bare` +and `detached`) are listed as a label only, and are present only +if the value is true. Some attributes (like `locked`) can be listed as a label +only or with a value depending upon whether a reason is available. The first +attribute of a working tree is always `worktree`, an empty line indicates the +end of the record. For example: ------------ $ git worktree list --porcelain @@ -349,6 +432,33 @@ worktree /path/to/other-linked-worktree HEAD 1234abc1234abc1234abc1234abc1234abc1234a detached +worktree /path/to/linked-worktree-locked-no-reason +HEAD 5678abc5678abc5678abc5678abc5678abc5678c +branch refs/heads/locked-no-reason +locked + +worktree /path/to/linked-worktree-locked-with-reason +HEAD 3456def3456def3456def3456def3456def3456b +branch refs/heads/locked-with-reason +locked reason why is locked + +worktree /path/to/linked-worktree-prunable +HEAD 1233def1234def1234def1234def1234def1234b +detached +prunable gitdir file points to non-existent location + +------------ + +If the lock reason contains "unusual" characters such as newline, they +are escaped and the entire reason is quoted as explained for the +configuration variable `core.quotePath` (see linkgit:git-config[1]). +For Example: + +------------ +$ git worktree list --porcelain +... +locked "reason\nwhy is locked" +... ------------ EXAMPLES diff --git a/Documentation/git.txt b/Documentation/git.txt index 81f7ecd52c..6dd241ef83 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -13,7 +13,7 @@ SYNOPSIS [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] - [--super-prefix=<path>] + [--super-prefix=<path>] [--config-env=<name>=<envvar>] <command> [<args>] DESCRIPTION @@ -33,7 +33,8 @@ individual Git commands with "git help command". linkgit:gitcli[7] manual page gives you an overview of the command-line command syntax. A formatted and hyperlinked copy of the latest Git documentation -can be viewed at `https://git.github.io/htmldocs/git.html`. +can be viewed at https://git.github.io/htmldocs/git.html +or https://git-scm.com/docs. OPTIONS @@ -79,6 +80,28 @@ config file). Including the equals but with an empty value (like `git -c foo.bar= ...`) sets `foo.bar` to the empty string which `git config --type=bool` will convert to `false`. +--config-env=<name>=<envvar>:: + Like `-c <name>=<value>`, give configuration variable + '<name>' a value, where <envvar> is the name of an + environment variable from which to retrieve the value. Unlike + `-c` there is no shortcut for directly setting the value to an + empty string, instead the environment variable itself must be + set to the empty string. It is an error if the `<envvar>` does not exist + in the environment. `<envvar>` may not contain an equals sign + to avoid ambiguity with `<name>` containing one. ++ +This is useful for cases where you want to pass transitory +configuration options to git, but are doing so on OS's where +other processes might be able to read your cmdline +(e.g. `/proc/self/cmdline`), but not your environ +(e.g. `/proc/self/environ`). That behavior is the default on +Linux, but may not be on your system. ++ +Note that this might add security for variables such as +`http.extraHeader` where the sensitive information is part of +the value, but not e.g. `url.<base>.insteadOf` where the +sensitive information can be part of the key. + --exec-path[=<path>]:: Path to wherever your core Git programs are installed. This can also be controlled by setting the GIT_EXEC_PATH @@ -109,9 +132,23 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config Do not pipe Git output into a pager. --git-dir=<path>:: - Set the path to the repository. This can also be controlled by - setting the `GIT_DIR` environment variable. It can be an absolute - path or relative path to current working directory. + Set the path to the repository (".git" directory). This can also be + controlled by setting the `GIT_DIR` environment variable. It can be + an absolute path or relative path to current working directory. ++ +Specifying the location of the ".git" directory using this +option (or `GIT_DIR` environment variable) turns off the +repository discovery that tries to find a directory with +".git" subdirectory (which is how the repository and the +top-level of the working tree are discovered), and tells Git +that you are at the top level of the working tree. If you +are not at the top-level directory of the working tree, you +should tell Git where the top-level of the working tree is, +with the `--work-tree=<path>` option (or `GIT_WORK_TREE` +environment variable) ++ +If you just want to run git as if it was started in `<path>` then use +`git -C <path>`. --work-tree=<path>:: Set the path to the working tree. It can be an absolute path @@ -211,6 +248,26 @@ people via patch over e-mail. include::cmds-foreignscminterface.txt[] +Reset, restore and revert +~~~~~~~~~~~~~~~~~~~~~~~~~ +There are three commands with similar names: `git reset`, +`git restore` and `git revert`. + +* linkgit:git-revert[1] is about making a new commit that reverts the + changes made by other commits. + +* linkgit:git-restore[1] is about restoring files in the working tree + from either the index or another commit. This command does not + update your branch. The command can also be used to restore files in + the index from another commit. + +* linkgit:git-reset[1] is about updating your branch, moving the tip + in order to add or remove commits from the branch. This operation + changes the commit history. ++ +`git reset` can also be used to restore the index, overlapping with +`git restore`. + Low-level commands (plumbing) ----------------------------- @@ -250,8 +307,8 @@ In general, the interrogate commands do not touch the files in the working tree. -Synching repositories -~~~~~~~~~~~~~~~~~~~~~ +Syncing repositories +~~~~~~~~~~~~~~~~~~~~ include::cmds-synchingrepositories.txt[] @@ -269,6 +326,13 @@ users typically do not use them directly. include::cmds-purehelpers.txt[] +Guides +------ + +The following documentation pages are guides about Git concepts. + +include::cmds-guide.txt[] + Configuration Mechanism ----------------------- @@ -458,16 +522,46 @@ double-quotes and respecting backslash escapes. E.g., the value details. This variable has lower precedence than other path variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY... +`GIT_DEFAULT_HASH`:: + If this variable is set, the default hash algorithm for new + repositories will be set to this value. This value is currently + ignored when cloning; the setting of the remote repository + is used instead. The default is "sha1". THIS VARIABLE IS + EXPERIMENTAL! See `--object-format` in linkgit:git-init[1]. + Git Commits ~~~~~~~~~~~ `GIT_AUTHOR_NAME`:: + The human-readable name used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.name` and + `author.name` configuration settings. + `GIT_AUTHOR_EMAIL`:: + The email address used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.email` and + `author.email` configuration settings. + `GIT_AUTHOR_DATE`:: + The date used for the author identity when creating commit or tag objects, or + when writing reflogs. See linkgit:git-commit[1] for valid formats. + `GIT_COMMITTER_NAME`:: + The human-readable name used in the committer identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.name` and + `committer.name` configuration settings. + `GIT_COMMITTER_EMAIL`:: + The email address used in the author identity when creating commit or + tag objects, or when writing reflogs. Overrides the `user.email` and + `committer.email` configuration settings. + `GIT_COMMITTER_DATE`:: -'EMAIL':: - see linkgit:git-commit-tree[1] + The date used for the committer identity when creating commit or tag objects, or + when writing reflogs. See linkgit:git-commit[1] for valid formats. + +`EMAIL`:: + The email address used in the author and committer identities if no other + relevant environment variable or configuration setting has been set. Git Diffs ~~~~~~~~~ @@ -479,8 +573,9 @@ Git Diffs `GIT_EXTERNAL_DIFF`:: When the environment variable `GIT_EXTERNAL_DIFF` is set, the - program named by it is called, instead of the diff invocation - described above. For a path that is added, removed, or modified, + program named by it is called to generate diffs, and Git + does not use its builtin diff machinery. + For a path that is added, removed, or modified, `GIT_EXTERNAL_DIFF` is called with 7 parameters: path old-file old-hex old-mode new-file new-hex new-mode @@ -523,12 +618,22 @@ other a pager. See also the `core.pager` option in linkgit:git-config[1]. +`GIT_PROGRESS_DELAY`:: + A number controlling how many seconds to delay before showing + optional progress indicators. Defaults to 2. + `GIT_EDITOR`:: This environment variable overrides `$EDITOR` and `$VISUAL`. It is used by several Git commands when, on interactive mode, an editor is to be launched. See also linkgit:git-var[1] and the `core.editor` option in linkgit:git-config[1]. +`GIT_SEQUENCE_EDITOR`:: + This environment variable overrides the configured Git editor + when editing the todo list of an interactive rebase. See also + linkgit:git-rebase[1] and the `sequence.editor` option in + linkgit:git-config[1]. + `GIT_SSH`:: `GIT_SSH_COMMAND`:: If either of these environment variables is set then 'git fetch' @@ -565,6 +670,16 @@ for further details. If this environment variable is set to `0`, git will not prompt on the terminal (e.g., when asking for HTTP authentication). +`GIT_CONFIG_GLOBAL`:: +`GIT_CONFIG_SYSTEM`:: + Take the configuration from the given files instead from global or + system-level configuration files. If `GIT_CONFIG_SYSTEM` is set, the + system config file defined at build time (usually `/etc/gitconfig`) + will not be read. Likewise, if `GIT_CONFIG_GLOBAL` is set, neither + `$HOME/.gitconfig` nor `$XDG_CONFIG_HOME/git/config` will be read. Can + be set to `/dev/null` to skip reading configuration files of the + respective level. + `GIT_CONFIG_NOSYSTEM`:: Whether to skip reading settings from the system-wide `$(prefix)/etc/gitconfig` file. This environment variable can @@ -639,6 +754,10 @@ of clones and fetches. time of each Git command. See `GIT_TRACE` for available trace output options. +`GIT_TRACE_REFS`:: + Enables trace messages for operations on the ref database. + See `GIT_TRACE` for available trace output options. + `GIT_TRACE_SETUP`:: Enables trace messages printing the .git, working tree and current working directory after Git has completed its setup phase. @@ -653,8 +772,6 @@ of clones and fetches. Enables a curl full trace dump of all incoming and outgoing data, including descriptive information, of the git transport protocol. This is similar to doing curl `--trace-ascii` on the command line. - This option overrides setting the `GIT_CURL_VERBOSE` environment - variable. See `GIT_TRACE` for available trace output options. `GIT_TRACE_CURL_NO_DATA`:: @@ -709,11 +826,10 @@ for full details. See `GIT_TRACE2` for available trace output options and link:technical/api-trace2.html[Trace2 documentation] for full details. -`GIT_REDACT_COOKIES`:: - This can be set to a comma-separated list of strings. When a curl trace - is enabled (see `GIT_TRACE_CURL` above), whenever a "Cookies:" header - sent by the client is dumped, values of cookies whose key is in that - list (case-sensitive) are redacted. +`GIT_TRACE_REDACT`:: + By default, when tracing is activated, Git redacts the values of + cookies, the "Authorization:" header, and the "Proxy-Authorization:" + header. Set this variable to `0` to prevent this redaction. `GIT_LITERAL_PATHSPECS`:: Setting this variable to `1` will cause Git to treat all @@ -907,7 +1023,7 @@ Reporting Bugs Report bugs to the Git mailing list <git@vger.kernel.org> where the development and maintenance is primarily done. You do not have to be subscribed to the list to send a message there. See the list archive -at https://public-inbox.org/git for previous bug reports and other +at https://lore.kernel.org/git for previous bug reports and other discussions. Issues which are security relevant should be disclosed privately to diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 4fb20cd0e9..83fd4e19a4 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -112,7 +112,8 @@ Checking-out and checking-in These attributes affect how the contents stored in the repository are copied to the working tree files when commands -such as 'git checkout' and 'git merge' run. They also affect how +such as 'git switch', 'git checkout' and 'git merge' run. +They also affect how Git stores the contents you prepare in the working tree in the repository upon 'git add' and 'git commit'. @@ -292,10 +293,10 @@ web front ends do not visualize the contents of these files by default. In these cases you can tell Git the encoding of a file in the working directory with the `working-tree-encoding` attribute. If a file with this -attribute is added to Git, then Git reencodes the content from the +attribute is added to Git, then Git re-encodes the content from the specified encoding to UTF-8. Finally, Git stores the UTF-8 encoded content in its internal data structure (called "the index"). On checkout -the content is reencoded back to the specified encoding. +the content is re-encoded back to the specified encoding. Please note that using the `working-tree-encoding` attribute may have a number of pitfalls: @@ -497,7 +498,7 @@ command. This is achieved by using the long-running process protocol When Git encounters the first file that needs to be cleaned or smudged, it starts the filter and performs the handshake. In the handshake, the welcome message sent by Git is "git-filter-client", only version 2 is -suppported, and the supported capabilities are "clean", "smudge", and +supported, and the supported capabilities are "clean", "smudge", and "delay". Afterwards Git sends a list of "key=value" pairs terminated with @@ -801,6 +802,9 @@ patterns are available: - `ada` suitable for source code in the Ada language. +- `bash` suitable for source code in the Bourne-Again SHell language. + Covers a superset of POSIX shell function definitions. + - `bibtex` suitable for files with BibTeX coded references. - `cpp` suitable for source code in the C and C++ languages. @@ -809,6 +813,10 @@ patterns are available: - `css` suitable for cascading style sheets. +- `dts` suitable for devicetree (DTS) files. + +- `elixir` suitable for source code in the Elixir language. + - `fortran` suitable for source code in the Fortran language. - `fountain` suitable for Fountain documents. @@ -819,7 +827,9 @@ patterns are available: - `java` suitable for source code in the Java language. -- `matlab` suitable for source code in the MATLAB language. +- `markdown` suitable for Markdown documents. + +- `matlab` suitable for source code in the MATLAB and Octave languages. - `objc` suitable for source code in the Objective-C language. @@ -833,6 +843,10 @@ patterns are available: - `ruby` suitable for source code in the Ruby language. +- `rust` suitable for source code in the Rust language. + +- `scheme` suitable for source code in the Scheme language. + - `tex` suitable for source code for LaTeX documents. @@ -1162,7 +1176,8 @@ tag then no replacement will be done. The placeholders are the same as those for the option `--pretty=format:` of linkgit:git-log[1], except that they need to be wrapped like this: `$Format:PLACEHOLDERS$` in the file. E.g. the string `$Format:%H$` will be replaced by the -commit hash. +commit hash. However, only one `%(describe)` placeholder is expanded +per archive to avoid denial-of-service attacks. Packing objects @@ -1232,6 +1247,12 @@ to: [attr]binary -diff -merge -text ------------ +NOTES +----- + +Git does not follow symbolic links when accessing a `.gitattributes` +file in the working tree. This keeps behavior consistent when the file +is accessed from the index or a tree versus from the filesystem. EXAMPLES -------- diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.txt index 592e06d839..92e4ba6a2f 100644 --- a/Documentation/gitcli.txt +++ b/Documentation/gitcli.txt @@ -37,6 +37,12 @@ arguments. Here are the rules: file called HEAD in your work tree, `git diff HEAD` is ambiguous, and you have to say either `git diff HEAD --` or `git diff -- HEAD` to disambiguate. + + * Because `--` disambiguates revisions and paths in some commands, it + cannot be used for those commands to separate options and revisions. + You can use `--end-of-options` for this (it also works for commands + that do not distinguish between revisions in paths, in which case it + is simply an alias for `--`). + When writing a script that is expected to handle random user-input, it is a good practice to make it explicit which arguments are which by placing @@ -47,8 +53,8 @@ disambiguating `--` at appropriate places. things: + -------------------------------- -$ git checkout -- *.c -$ git checkout -- \*.c +$ git restore *.c +$ git restore \*.c -------------------------------- + The former lets your shell expand the fileglob, and you are asking @@ -120,6 +126,11 @@ usage: git describe [<options>] <commit-ish>* --long always use long format --abbrev[=<n>] use <n> digits to display SHA-1s --------------------------------------------- ++ +Note that some subcommand (e.g. `git grep`) may behave differently +when there are things on the command line other than `-h`, but `git +subcmd -h` without anything else on the command line is meant to +consistently give the usage. --help-all:: Some Git commands take options that are only used for plumbing or that @@ -205,10 +216,22 @@ only affects the files in the working tree, but with entries, and with `--cached`, it modifies only the index entries. -See also http://marc.info/?l=git&m=116563135620359 and -http://marc.info/?l=git&m=119150393620273 for further +See also https://lore.kernel.org/git/7v64clg5u9.fsf@assigned-by-dhcp.cox.net/ and +https://lore.kernel.org/git/7vy7ej9g38.fsf@gitster.siamese.dyndns.org/ for further information. +Some other commands that also work on files in the working tree and/or +in the index can take `--staged` and/or `--worktree`. + +* `--staged` is exactly like `--cached`, which is used to ask a + command to only work on the index, not the working tree. + +* `--worktree` is the opposite, to ask a command to work on the + working tree only, not the index. + +* The two options can be specified together to ask a command to work + on both the index and the working tree. + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.txt index e29a9effcc..c0b95256cc 100644 --- a/Documentation/gitcore-tutorial.txt +++ b/Documentation/gitcore-tutorial.txt @@ -741,7 +741,7 @@ used earlier, and create a branch in it. You do that by simply just saying that you want to check out a new branch: ------------ -$ git checkout -b mybranch +$ git switch -c mybranch ------------ will create a new branch based at the current `HEAD` position, and switch @@ -751,11 +751,11 @@ to it. ================================================ If you make the decision to start your new branch at some other point in the history than the current `HEAD`, you can do so by -just telling 'git checkout' what the base of the checkout would be. +just telling 'git switch' what the base of the checkout would be. In other words, if you have an earlier tag or branch, you'd just do ------------ -$ git checkout -b mybranch earlier-commit +$ git switch -c mybranch earlier-commit ------------ and it would create the new branch `mybranch` at the earlier commit, @@ -765,7 +765,7 @@ and check out the state at that time. You can always just jump back to your original `master` branch by doing ------------ -$ git checkout master +$ git switch master ------------ (or any other branch-name, for that matter) and if you forget which @@ -794,7 +794,7 @@ $ git branch <branchname> [startingpoint] which will simply _create_ the branch, but will not do anything further. You can then later -- once you decide that you want to actually develop -on that branch -- switch to that branch with a regular 'git checkout' +on that branch -- switch to that branch with a regular 'git switch' with the branchname as the argument. @@ -808,7 +808,7 @@ being the same as the original `master` branch, let's make sure we're in that branch, and do some work there. ------------------------------------------------ -$ git checkout mybranch +$ git switch mybranch $ echo "Work, work, work" >>hello $ git commit -m "Some work." -i hello ------------------------------------------------ @@ -825,7 +825,7 @@ does some work in the original branch, and simulate that by going back to the master branch, and editing the same file differently there: ------------ -$ git checkout master +$ git switch master ------------ Here, take a moment to look at the contents of `hello`, and notice how they @@ -958,7 +958,7 @@ to the `master` branch. Let's go back to `mybranch`, and run 'git merge' to get the "upstream changes" back to your branch. ------------ -$ git checkout mybranch +$ git switch mybranch $ git merge -m "Merge upstream changes." master ------------ @@ -1133,9 +1133,8 @@ Remember, before running 'git merge', our `master` head was at work." commit. ------------ -$ git checkout mybranch -$ git reset --hard master^2 -$ git checkout master +$ git switch -C mybranch master^2 +$ git switch master $ git reset --hard master^ ------------ diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt index adc759612d..758bf39ba3 100644 --- a/Documentation/gitcredentials.txt +++ b/Documentation/gitcredentials.txt @@ -3,7 +3,7 @@ gitcredentials(7) NAME ---- -gitcredentials - providing usernames and passwords to Git +gitcredentials - Providing usernames and passwords to Git SYNOPSIS -------- @@ -131,7 +131,9 @@ context would not match: because the hostnames differ. Nor would it match `foo.example.com`; Git compares hostnames exactly, without considering whether two hosts are part of the same domain. Likewise, a config entry for `http://example.com` would not -match: Git compares the protocols exactly. +match: Git compares the protocols exactly. However, you may use wildcards in +the domain name and other pattern matching techniques as with the `http.<url>.*` +options. If the "pattern" URL does include a path component, then this too must match exactly: the context `https://example.com/bar/baz.git` will match a config @@ -186,8 +188,110 @@ CUSTOM HELPERS -------------- You can write your own custom helpers to interface with any system in -which you keep credentials. See the documentation for Git's -link:technical/api-credentials.html[credentials API] for details. +which you keep credentials. + +Credential helpers are programs executed by Git to fetch or save +credentials from and to long-term storage (where "long-term" is simply +longer than a single Git process; e.g., credentials may be stored +in-memory for a few minutes, or indefinitely on disk). + +Each helper is specified by a single string in the configuration +variable `credential.helper` (and others, see linkgit:git-config[1]). +The string is transformed by Git into a command to be executed using +these rules: + + 1. If the helper string begins with "!", it is considered a shell + snippet, and everything after the "!" becomes the command. + + 2. Otherwise, if the helper string begins with an absolute path, the + verbatim helper string becomes the command. + + 3. Otherwise, the string "git credential-" is prepended to the helper + string, and the result becomes the command. + +The resulting command then has an "operation" argument appended to it +(see below for details), and the result is executed by the shell. + +Here are some example specifications: + +---------------------------------------------------- +# run "git credential-foo" +[credential] + helper = foo + +# same as above, but pass an argument to the helper +[credential] + helper = "foo --bar=baz" + +# the arguments are parsed by the shell, so use shell +# quoting if necessary +[credential] + helper = "foo --bar='whitespace arg'" + +# you can also use an absolute path, which will not use the git wrapper +[credential] + helper = "/path/to/my/helper --with-arguments" + +# or you can specify your own shell snippet +[credential "https://example.com"] + username = your_user + helper = "!f() { test \"$1\" = get && echo \"password=$(cat $HOME/.secret)\"; }; f" +---------------------------------------------------- + +Generally speaking, rule (3) above is the simplest for users to specify. +Authors of credential helpers should make an effort to assist their +users by naming their program "git-credential-$NAME", and putting it in +the `$PATH` or `$GIT_EXEC_PATH` during installation, which will allow a +user to enable it with `git config credential.helper $NAME`. + +When a helper is executed, it will have one "operation" argument +appended to its command line, which is one of: + +`get`:: + + Return a matching credential, if any exists. + +`store`:: + + Store the credential, if applicable to the helper. + +`erase`:: + + Remove a matching credential, if any, from the helper's storage. + +The details of the credential will be provided on the helper's stdin +stream. The exact format is the same as the input/output format of the +`git credential` plumbing command (see the section `INPUT/OUTPUT +FORMAT` in linkgit:git-credential[1] for a detailed specification). + +For a `get` operation, the helper should produce a list of attributes on +stdout in the same format (see linkgit:git-credential[1] for common +attributes). A helper is free to produce a subset, or even no values at +all if it has nothing useful to provide. Any provided attributes will +overwrite those already known about by Git's credential subsystem. + +While it is possible to override all attributes, well behaving helpers +should refrain from doing so for any attribute other than username and +password. + +If a helper outputs a `quit` attribute with a value of `true` or `1`, +no further helpers will be consulted, nor will the user be prompted +(if no credential has been provided, the operation will then fail). + +Similarly, no more helpers will be consulted once both username and +password had been provided. + +For a `store` or `erase` operation, the helper's output is ignored. + +If a helper fails to perform the requested operation or needs to notify +the user of a potential issue, it may write to stderr. + +If it does not support the requested operation (e.g., a read-only store), +it should silently ignore the request. + +If a helper receives any other operation, it should silently ignore the +request. This leaves room for future operations to be added (older +helpers will just ignore the new requests). GIT --- diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.txt index c970d9fe43..0d57f86abc 100644 --- a/Documentation/gitdiffcore.txt +++ b/Documentation/gitdiffcore.txt @@ -74,6 +74,7 @@ into another list. There are currently 5 such transformations: - diffcore-merge-broken - diffcore-pickaxe - diffcore-order +- diffcore-rotate These are applied in sequence. The set of filepairs 'git diff-{asterisk}' commands find are used as the input to diffcore-break, and @@ -168,6 +169,26 @@ a similarity score different from the default of 50% by giving a number after the "-M" or "-C" option (e.g. "-M8" to tell it to use 8/10 = 80%). +Note that when rename detection is on but both copy and break +detection are off, rename detection adds a preliminary step that first +checks if files are moved across directories while keeping their +filename the same. If there is a file added to a directory whose +contents is sufficiently similar to a file with the same name that got +deleted from a different directory, it will mark them as renames and +exclude them from the later quadratic step (the one that pairwise +compares all unmatched files to find the "best" matches, determined by +the highest content similarity). So, for example, if a deleted +docs/ext.txt and an added docs/config/ext.txt are similar enough, they +will be marked as a rename and prevent an added docs/ext.md that may +be even more similar to the deleted docs/ext.txt from being considered +as the rename destination in the later step. For this reason, the +preliminary "match same filename" step uses a bit higher threshold to +mark a file pair as a rename and stop considering other candidates for +better matches. At most, one comparison is done per file in this +preliminary pass; so if there are several remaining ext.txt files +throughout the directory hierarchy after exact rename detection, this +preliminary step may be skipped for those files. + Note. When the "-C" option is used with `--find-copies-harder` option, 'git diff-{asterisk}' commands feed unmodified filepairs to diffcore mechanism as well as modified ones. This lets the copy @@ -276,6 +297,26 @@ Documentation t ------------------------------------------------ +diffcore-rotate: For Changing At Which Path Output Starts +--------------------------------------------------------- + +This transformation takes one pathname, and rotates the set of +filepairs so that the filepair for the given pathname comes first, +optionally discarding the paths that come before it. This is used +to implement the `--skip-to` and the `--rotate-to` options. It is +an error when the specified pathname is not in the set of filepairs, +but it is not useful to error out when used with "git log" family of +commands, because it is unreasonable to expect that a given path +would be modified by each and every commit shown by the "git log" +command. For this reason, when used with "git log", the filepair +that sorts the same as, or the first one that sorts after, the given +pathname is where the output starts. + +Use of this transformation combined with diffcore-order will produce +unexpected results, as the input to this transformation is likely +not sorted when diffcore-order is in effect. + + SEE ALSO -------- linkgit:git-diff[1], diff --git a/Documentation/giteveryday.txt b/Documentation/giteveryday.txt index 9f2528fc8c..faba2ef088 100644 --- a/Documentation/giteveryday.txt +++ b/Documentation/giteveryday.txt @@ -41,7 +41,7 @@ following commands. * linkgit:git-log[1] to see what happened. - * linkgit:git-checkout[1] and linkgit:git-branch[1] to switch + * linkgit:git-switch[1] and linkgit:git-branch[1] to switch branches. * linkgit:git-add[1] to manage the index file. @@ -51,8 +51,7 @@ following commands. * linkgit:git-commit[1] to advance the current branch. - * linkgit:git-reset[1] and linkgit:git-checkout[1] (with - pathname parameters) to undo changes. + * linkgit:git-restore[1] to undo changes. * linkgit:git-merge[1] to merge between local branches. @@ -80,9 +79,9 @@ $ git tag v2.43 <2> Create a topic branch and develop.:: + ------------ -$ git checkout -b alsa-audio <1> +$ git switch -c alsa-audio <1> $ edit/compile/test -$ git checkout -- curses/ux_audio_oss.c <2> +$ git restore curses/ux_audio_oss.c <2> $ git add curses/ux_audio_alsa.c <3> $ edit/compile/test $ git diff HEAD <4> @@ -90,7 +89,7 @@ $ git commit -a -s <5> $ edit/compile/test $ git diff HEAD^ <6> $ git commit -a --amend <7> -$ git checkout master <8> +$ git switch master <8> $ git merge alsa-audio <9> $ git log --since='3 days ago' <10> $ git log v2.43.. curses/ <11> @@ -148,11 +147,11 @@ Clone the upstream and work on it. Feed changes to upstream.:: ------------ $ git clone git://git.kernel.org/pub/scm/.../torvalds/linux-2.6 my2.6 $ cd my2.6 -$ git checkout -b mine master <1> +$ git switch -c mine master <1> $ edit/compile/test; git commit -a -s <2> $ git format-patch master <3> $ git send-email --to="person <email@example.com>" 00*.patch <4> -$ git checkout master <5> +$ git switch master <5> $ git pull <6> $ git log -p ORIG_HEAD.. arch/i386 include/asm-i386 <7> $ git ls-remote --heads http://git.kernel.org/.../jgarzik/libata-dev.git <8> @@ -194,7 +193,7 @@ satellite$ edit/compile/test/commit satellite$ git push origin <4> mothership$ cd frotz -mothership$ git checkout master +mothership$ git switch master mothership$ git merge satellite/master <5> ------------ + @@ -216,7 +215,7 @@ machine into the master branch. Branch off of a specific tag.:: + ------------ -$ git checkout -b private2.6.14 v2.6.14 <1> +$ git switch -c private2.6.14 v2.6.14 <1> $ edit/compile/test; git commit -a $ git checkout master $ git cherry-pick v2.6.14..private2.6.14 <2> @@ -274,18 +273,18 @@ $ mailx <3> & s 2 3 4 5 ./+to-apply & s 7 8 ./+hold-linus & q -$ git checkout -b topic/one master +$ git switch -c topic/one master $ git am -3 -i -s ./+to-apply <4> $ compile/test -$ git checkout -b hold/linus && git am -3 -i -s ./+hold-linus <5> -$ git checkout topic/one && git rebase master <6> -$ git checkout pu && git reset --hard next <7> +$ git switch -c hold/linus && git am -3 -i -s ./+hold-linus <5> +$ git switch topic/one && git rebase master <6> +$ git switch -C seen next <7> $ git merge topic/one topic/two && git merge hold/linus <8> -$ git checkout maint +$ git switch maint $ git cherry-pick master~4 <9> $ compile/test $ git tag -s -m "GIT 0.99.9x" v0.99.9x <10> -$ git fetch ko && for branch in master maint next pu <11> +$ git fetch ko && for branch in master maint next seen <11> do git show-branch ko/$branch $branch <12> done @@ -295,14 +294,14 @@ $ git push --follow-tags ko <13> <1> see what you were in the middle of doing, if anything. <2> see which branches haven't been merged into `master` yet. Likewise for any other integration branches e.g. `maint`, `next` -and `pu` (potential updates). +and `seen`. <3> read mails, save ones that are applicable, and save others that are not quite ready (other mail readers are available). <4> apply them, interactively, with your sign-offs. <5> create topic branch as needed and apply, again with sign-offs. <6> rebase internal topic branch that has not been merged to the master or exposed as a part of a stable branch. -<7> restart `pu` every time from the next. +<7> restart `seen` every time from the next. <8> and bundle topic branches still cooking. <9> backport a critical fix. <10> create a signed tag. @@ -324,7 +323,7 @@ repository at kernel.org, and looks like this: fetch = refs/heads/*:refs/remotes/ko/* push = refs/heads/master push = refs/heads/next - push = +refs/heads/pu + push = +refs/heads/seen push = refs/heads/maint ------------ diff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt new file mode 100644 index 0000000000..8c1f2d5675 --- /dev/null +++ b/Documentation/gitfaq.txt @@ -0,0 +1,441 @@ +gitfaq(7) +========= + +NAME +---- +gitfaq - Frequently asked questions about using Git + +SYNOPSIS +-------- +gitfaq + +DESCRIPTION +----------- + +The examples in this FAQ assume a standard POSIX shell, like `bash` or `dash`, +and a user, A U Thor, who has the account `author` on the hosting provider +`git.example.org`. + +Configuration +------------- + +[[user-name]] +What should I put in `user.name`?:: + You should put your personal name, generally a form using a given name + and family name. For example, the current maintainer of Git uses "Junio + C Hamano". This will be the name portion that is stored in every commit + you make. ++ +This configuration doesn't have any effect on authenticating to remote services; +for that, see `credential.username` in linkgit:git-config[1]. + +[[http-postbuffer]] +What does `http.postBuffer` really do?:: + This option changes the size of the buffer that Git uses when pushing + data to a remote over HTTP or HTTPS. If the data is larger than this + size, libcurl, which handles the HTTP support for Git, will use chunked + transfer encoding since it isn't known ahead of time what the size of + the pushed data will be. ++ +Leaving this value at the default size is fine unless you know that either the +remote server or a proxy in the middle doesn't support HTTP/1.1 (which +introduced the chunked transfer encoding) or is known to be broken with chunked +data. This is often (erroneously) suggested as a solution for generic push +problems, but since almost every server and proxy supports at least HTTP/1.1, +raising this value usually doesn't solve most push problems. A server or proxy +that didn't correctly support HTTP/1.1 and chunked transfer encoding wouldn't be +that useful on the Internet today, since it would break lots of traffic. ++ +Note that increasing this value will increase the memory used on every relevant +push that Git does over HTTP or HTTPS, since the entire buffer is allocated +regardless of whether or not it is all used. Thus, it's best to leave it at the +default unless you are sure you need a different value. + +[[configure-editor]] +How do I configure a different editor?:: + If you haven't specified an editor specifically for Git, it will by default + use the editor you've configured using the `VISUAL` or `EDITOR` environment + variables, or if neither is specified, the system default (which is usually + `vi`). Since some people find `vi` difficult to use or prefer a different + editor, it may be desirable to change the editor used. ++ +If you want to configure a general editor for most programs which need one, you +can edit your shell configuration (e.g., `~/.bashrc` or `~/.zshenv`) to contain +a line setting the `EDITOR` or `VISUAL` environment variable to an appropriate +value. For example, if you prefer the editor `nano`, then you could write the +following: ++ +---- +export VISUAL=nano +---- ++ +If you want to configure an editor specifically for Git, you can either set the +`core.editor` configuration value or the `GIT_EDITOR` environment variable. You +can see linkgit:git-var[1] for details on the order in which these options are +consulted. ++ +Note that in all cases, the editor value will be passed to the shell, so any +arguments containing spaces should be appropriately quoted. Additionally, if +your editor normally detaches from the terminal when invoked, you should specify +it with an argument that makes it not do that, or else Git will not see any +changes. An example of a configuration addressing both of these issues on +Windows would be the configuration `"C:\Program Files\Vim\gvim.exe" --nofork`, +which quotes the filename with spaces and specifies the `--nofork` option to +avoid backgrounding the process. + +Credentials +----------- + +[[http-credentials]] +How do I specify my credentials when pushing over HTTP?:: + The easiest way to do this is to use a credential helper via the + `credential.helper` configuration. Most systems provide a standard + choice to integrate with the system credential manager. For example, + Git for Windows provides the `wincred` credential manager, macOS has the + `osxkeychain` credential manager, and Unix systems with a standard + desktop environment can use the `libsecret` credential manager. All of + these store credentials in an encrypted store to keep your passwords or + tokens secure. ++ +In addition, you can use the `store` credential manager which stores in a file +in your home directory, or the `cache` credential manager, which does not +permanently store your credentials, but does prevent you from being prompted for +them for a certain period of time. ++ +You can also just enter your password when prompted. While it is possible to +place the password (which must be percent-encoded) in the URL, this is not +particularly secure and can lead to accidental exposure of credentials, so it is +not recommended. + +[[http-credentials-environment]] +How do I read a password or token from an environment variable?:: + The `credential.helper` configuration option can also take an arbitrary + shell command that produces the credential protocol on standard output. + This is useful when passing credentials into a container, for example. ++ +Such a shell command can be specified by starting the option value with an +exclamation point. If your password or token were stored in the `GIT_TOKEN`, +you could run the following command to set your credential helper: ++ +---- +$ git config credential.helper \ + '!f() { echo username=author; echo "password=$GIT_TOKEN"; };f' +---- + +[[http-reset-credentials]] +How do I change the password or token I've saved in my credential manager?:: + Usually, if the password or token is invalid, Git will erase it and + prompt for a new one. However, there are times when this doesn't always + happen. To change the password or token, you can erase the existing + credentials and then Git will prompt for new ones. To erase + credentials, use a syntax like the following (substituting your username + and the hostname): ++ +---- +$ echo url=https://author@git.example.org | git credential reject +---- + +[[multiple-accounts-http]] +How do I use multiple accounts with the same hosting provider using HTTP?:: + Usually the easiest way to distinguish between these accounts is to use + the username in the URL. For example, if you have the accounts `author` + and `committer` on `git.example.org`, you can use the URLs + https://author@git.example.org/org1/project1.git and + https://committer@git.example.org/org2/project2.git. This way, when you + use a credential helper, it will automatically try to look up the + correct credentials for your account. If you already have a remote set + up, you can change the URL with something like `git remote set-url + origin https://author@git.example.org/org1/project1.git` (see + linkgit:git-remote[1] for details). + +[[multiple-accounts-ssh]] +How do I use multiple accounts with the same hosting provider using SSH?:: + With most hosting providers that support SSH, a single key pair uniquely + identifies a user. Therefore, to use multiple accounts, it's necessary + to create a key pair for each account. If you're using a reasonably + modern OpenSSH version, you can create a new key pair with something + like `ssh-keygen -t ed25519 -f ~/.ssh/id_committer`. You can then + register the public key (in this case, `~/.ssh/id_committer.pub`; note + the `.pub`) with the hosting provider. ++ +Most hosting providers use a single SSH account for pushing; that is, all users +push to the `git` account (e.g., `git@git.example.org`). If that's the case for +your provider, you can set up multiple aliases in SSH to make it clear which key +pair to use. For example, you could write something like the following in +`~/.ssh/config`, substituting the proper private key file: ++ +---- +# This is the account for author on git.example.org. +Host example_author + HostName git.example.org + User git + # This is the key pair registered for author with git.example.org. + IdentityFile ~/.ssh/id_author + IdentitiesOnly yes +# This is the account for committer on git.example.org. +Host example_committer + HostName git.example.org + User git + # This is the key pair registered for committer with git.example.org. + IdentityFile ~/.ssh/id_committer + IdentitiesOnly yes +---- ++ +Then, you can adjust your push URL to use `git@example_author` or +`git@example_committer` instead of `git@example.org` (e.g., `git remote set-url +git@example_author:org1/project1.git`). + +Common Issues +------------- + +[[last-commit-amend]] +I've made a mistake in the last commit. How do I change it?:: + You can make the appropriate change to your working tree, run `git add + <file>` or `git rm <file>`, as appropriate, to stage it, and then `git + commit --amend`. Your change will be included in the commit, and you'll + be prompted to edit the commit message again; if you wish to use the + original message verbatim, you can use the `--no-edit` option to `git + commit` in addition, or just save and quit when your editor opens. + +[[undo-previous-change]] +I've made a change with a bug and it's been included in the main branch. How should I undo it?:: + The usual way to deal with this is to use `git revert`. This preserves + the history that the original change was made and was a valuable + contribution, but also introduces a new commit that undoes those changes + because the original had a problem. The commit message of the revert + indicates the commit which was reverted and is usually edited to include + an explanation as to why the revert was made. + +[[ignore-tracked-files]] +How do I ignore changes to a tracked file?:: + Git doesn't provide a way to do this. The reason is that if Git needs + to overwrite this file, such as during a checkout, it doesn't know + whether the changes to the file are precious and should be kept, or + whether they are irrelevant and can safely be destroyed. Therefore, it + has to take the safe route and always preserve them. ++ +It's tempting to try to use certain features of `git update-index`, namely the +assume-unchanged and skip-worktree bits, but these don't work properly for this +purpose and shouldn't be used this way. ++ +If your goal is to modify a configuration file, it can often be helpful to have +a file checked into the repository which is a template or set of defaults which +can then be copied alongside and modified as appropriate. This second, modified +file is usually ignored to prevent accidentally committing it. + +[[files-in-gitignore-are-tracked]] +I asked Git to ignore various files, yet they are still tracked:: + A `gitignore` file ensures that certain file(s) which are not + tracked by Git remain untracked. However, sometimes particular + file(s) may have been tracked before adding them into the + `.gitignore`, hence they still remain tracked. To untrack and + ignore files/patterns, use `git rm --cached <file/pattern>` + and add a pattern to `.gitignore` that matches the <file>. + See linkgit:gitignore[5] for details. + +[[fetching-and-pulling]] +How do I know if I want to do a fetch or a pull?:: + A fetch stores a copy of the latest changes from the remote + repository, without modifying the working tree or current branch. + You can then at your leisure inspect, merge, rebase on top of, or + ignore the upstream changes. A pull consists of a fetch followed + immediately by either a merge or rebase. See linkgit:git-pull[1]. + +Merging and Rebasing +-------------------- + +[[long-running-squash-merge]] +What kinds of problems can occur when merging long-lived branches with squash merges?:: + In general, there are a variety of problems that can occur when using squash + merges to merge two branches multiple times. These can include seeing extra + commits in `git log` output, with a GUI, or when using the `...` notation to + express a range, as well as the possibility of needing to re-resolve conflicts + again and again. ++ +When Git does a normal merge between two branches, it considers exactly three +points: the two branches and a third commit, called the _merge base_, which is +usually the common ancestor of the commits. The result of the merge is the sum +of the changes between the merge base and each head. When you merge two +branches with a regular merge commit, this results in a new commit which will +end up as a merge base when they're merged again, because there is now a new +common ancestor. Git doesn't have to consider changes that occurred before the +merge base, so you don't have to re-resolve any conflicts you resolved before. ++ +When you perform a squash merge, a merge commit isn't created; instead, the +changes from one side are applied as a regular commit to the other side. This +means that the merge base for these branches won't have changed, and so when Git +goes to perform its next merge, it considers all of the changes that it +considered the last time plus the new changes. That means any conflicts may +need to be re-resolved. Similarly, anything using the `...` notation in `git +diff`, `git log`, or a GUI will result in showing all of the changes since the +original merge base. ++ +As a consequence, if you want to merge two long-lived branches repeatedly, it's +best to always use a regular merge commit. + +[[merge-two-revert-one]] +If I make a change on two branches but revert it on one, why does the merge of those branches include the change?:: + By default, when Git does a merge, it uses a strategy called the `ort` + strategy, which does a fancy three-way merge. In such a case, when Git + performs the merge, it considers exactly three points: the two heads and a + third point, called the _merge base_, which is usually the common ancestor of + those commits. Git does not consider the history or the individual commits + that have happened on those branches at all. ++ +As a result, if both sides have a change and one side has reverted that change, +the result is to include the change. This is because the code has changed on +one side and there is no net change on the other, and in this scenario, Git +adopts the change. ++ +If this is a problem for you, you can do a rebase instead, rebasing the branch +with the revert onto the other branch. A rebase in this scenario will revert +the change, because a rebase applies each individual commit, including the +revert. Note that rebases rewrite history, so you should avoid rebasing +published branches unless you're sure you're comfortable with that. See the +NOTES section in linkgit:git-rebase[1] for more details. + +Hooks +----- + +[[restrict-with-hooks]] +How do I use hooks to prevent users from making certain changes?:: + The only safe place to make these changes is on the remote repository + (i.e., the Git server), usually in the `pre-receive` hook or in a + continuous integration (CI) system. These are the locations in which + policy can be enforced effectively. ++ +It's common to try to use `pre-commit` hooks (or, for commit messages, +`commit-msg` hooks) to check these things, which is great if you're working as a +solo developer and want the tooling to help you. However, using hooks on a +developer machine is not effective as a policy control because a user can bypass +these hooks with `--no-verify` without being noticed (among various other ways). +Git assumes that the user is in control of their local repositories and doesn't +try to prevent this or tattle on the user. ++ +In addition, some advanced users find `pre-commit` hooks to be an impediment to +workflows that use temporary commits to stage work in progress or that create +fixup commits, so it's better to push these kinds of checks to the server +anyway. + +Cross-Platform Issues +--------------------- + +[[windows-text-binary]] +I'm on Windows and my text files are detected as binary.:: + Git works best when you store text files as UTF-8. Many programs on + Windows support UTF-8, but some do not and only use the little-endian + UTF-16 format, which Git detects as binary. If you can't use UTF-8 with + your programs, you can specify a working tree encoding that indicates + which encoding your files should be checked out with, while still + storing these files as UTF-8 in the repository. This allows tools like + linkgit:git-diff[1] to work as expected, while still allowing your tools + to work. ++ +To do so, you can specify a linkgit:gitattributes[5] pattern with the +`working-tree-encoding` attribute. For example, the following pattern sets all +C files to use UTF-16LE-BOM, which is a common encoding on Windows: ++ +---- +*.c working-tree-encoding=UTF-16LE-BOM +---- ++ +You will need to run `git add --renormalize` to have this take effect. Note +that if you are making these changes on a project that is used across platforms, +you'll probably want to make it in a per-user configuration file or in the one +in `$GIT_DIR/info/attributes`, since making it in a `.gitattributes` file in the +repository will apply to all users of the repository. ++ +See the following entry for information about normalizing line endings as well, +and see linkgit:gitattributes[5] for more information about attribute files. + +[[windows-diff-control-m]] +I'm on Windows and git diff shows my files as having a `^M` at the end.:: + By default, Git expects files to be stored with Unix line endings. As such, + the carriage return (`^M`) that is part of a Windows line ending is shown + because it is considered to be trailing whitespace. Git defaults to showing + trailing whitespace only on new lines, not existing ones. ++ +You can store the files in the repository with Unix line endings and convert +them automatically to your platform's line endings. To do that, set the +configuration option `core.eol` to `native` and see the following entry for +information about how to configure files as text or binary. ++ +You can also control this behavior with the `core.whitespace` setting if you +don't wish to remove the carriage returns from your line endings. + +[[always-modified-files-case]] +Why do I have a file that's always modified?:: + Internally, Git always stores file names as sequences of bytes and doesn't + perform any encoding or case folding. However, Windows and macOS by default + both perform case folding on file names. As a result, it's possible to end up + with multiple files or directories whose names differ only in case. Git can + handle this just fine, but the file system can store only one of these files, + so when Git reads the other file to see its contents, it looks modified. ++ +It's best to remove one of the files such that you only have one file. You can +do this with commands like the following (assuming two files `AFile.txt` and +`afile.txt`) on an otherwise clean working tree: ++ +---- +$ git rm --cached AFile.txt +$ git commit -m 'Remove files conflicting in case' +$ git checkout . +---- ++ +This avoids touching the disk, but removes the additional file. Your project +may prefer to adopt a naming convention, such as all-lowercase names, to avoid +this problem from occurring again; such a convention can be checked using a +`pre-receive` hook or as part of a continuous integration (CI) system. ++ +It is also possible for perpetually modified files to occur on any platform if a +smudge or clean filter is in use on your system but a file was previously +committed without running the smudge or clean filter. To fix this, run the +following on an otherwise clean working tree: ++ +---- +$ git add --renormalize . +---- + +[[recommended-storage-settings]] +What's the recommended way to store files in Git?:: + While Git can store and handle any file of any type, there are some + settings that work better than others. In general, we recommend that + text files be stored in UTF-8 without a byte-order mark (BOM) with LF + (Unix-style) endings. We also recommend the use of UTF-8 (again, + without BOM) in commit messages. These are the settings that work best + across platforms and with tools such as `git diff` and `git merge`. ++ +Additionally, if you have a choice between storage formats that are text based +or non-text based, we recommend storing files in the text format and, if +necessary, transforming them into the other format. For example, a text-based +SQL dump with one record per line will work much better for diffing and merging +than an actual database file. Similarly, text-based formats such as Markdown +and AsciiDoc will work better than binary formats such as Microsoft Word and +PDF. ++ +Similarly, storing binary dependencies (e.g., shared libraries or JAR files) or +build products in the repository is generally not recommended. Dependencies and +build products are best stored on an artifact or package server with only +references, URLs, and hashes stored in the repository. ++ +We also recommend setting a linkgit:gitattributes[5] file to explicitly mark +which files are text and which are binary. If you want Git to guess, you can +set the attribute `text=auto`. For example, the following might be appropriate +in some projects: ++ +---- +# By default, guess. +* text=auto +# Mark all C files as text. +*.c text +# Mark all JPEG files as binary. +*.jpg binary +---- ++ +These settings help tools pick the right format for output such as patches and +result in files being checked out in the appropriate line ending for the +platform. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 786e778ab8..b51959ff94 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -103,6 +103,28 @@ The default 'pre-commit' hook, when enabled--and with the `hooks.allownonascii` config option unset or set to false--prevents the use of non-ASCII filenames. +pre-merge-commit +~~~~~~~~~~~~~~~~ + +This hook is invoked by linkgit:git-merge[1], and can be bypassed +with the `--no-verify` option. It takes no parameters, and is +invoked after the merge has been carried out successfully and before +obtaining the proposed commit log message to +make a commit. Exiting with a non-zero status from this script +causes the `git merge` command to abort before creating a commit. + +The default 'pre-merge-commit' hook, when enabled, runs the +'pre-commit' hook, if the latter is enabled. + +This hook is invoked with the environment variable +`GIT_EDITOR=:` if the command will not bring up an editor +to modify the commit message. + +If the merge cannot be carried out automatically, the conflicts +need to be resolved and the result committed separately (see +linkgit:git-merge[1]). At that point, this hook will not be executed, +but the 'pre-commit' hook will, if it is enabled. + prepare-commit-msg ~~~~~~~~~~~~~~~~~~ @@ -116,7 +138,7 @@ given); `template` (if a `-t` option was given or the configuration option `commit.template` is set); `merge` (if the commit is a merge or a `.git/MERGE_MSG` file exists); `squash` (if a `.git/SQUASH_MSG` file exists); or `commit`, followed by -a commit SHA-1 (if a `-c`, `-C` or `--amend` option was given). +a commit object name (if a `-c`, `-C` or `--amend` option was given). If the exit status is non-zero, `git commit` will abort. @@ -142,7 +164,7 @@ can also be used to refuse the commit after inspecting the message file. The default 'commit-msg' hook, when enabled, detects duplicate -"Signed-off-by" lines, and aborts the commit if one is found. +`Signed-off-by` trailers, and aborts the commit if one is found. post-commit ~~~~~~~~~~~ @@ -165,12 +187,15 @@ rebased, and is not set when rebasing the current branch. post-checkout ~~~~~~~~~~~~~ -This hook is invoked when a linkgit:git-checkout[1] is run after having updated the +This hook is invoked when a linkgit:git-checkout[1] or +linkgit:git-switch[1] is run after having updated the worktree. The hook is given three parameters: the ref of the previous HEAD, the ref of the new HEAD (which may or may not have changed), and a flag indicating whether the checkout was a branch checkout (changing branches, flag=1) or a file checkout (retrieving a file from the index, flag=0). -This hook cannot affect the outcome of `git checkout`. +This hook cannot affect the outcome of `git switch` or `git checkout`, +other than that the hook's exit status becomes the exit status of +these two commands. It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is used. The first parameter given to the hook is the null-ref, the second the @@ -206,19 +231,19 @@ named remote is not being used both values will be the same. Information about what is to be pushed is provided on the hook's standard input with lines of the form: - <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF + <local ref> SP <local object name> SP <remote ref> SP <remote object name> LF For instance, if the command +git push origin master:foreign+ were run the hook would receive a line like the following: refs/heads/master 67890 refs/heads/foreign 12345 -although the full, 40-character SHA-1s would be supplied. If the foreign ref -does not yet exist the `<remote SHA-1>` will be 40 `0`. If a ref is to be -deleted, the `<local ref>` will be supplied as `(delete)` and the `<local -SHA-1>` will be 40 `0`. If the local commit was specified by something other -than a name which could be expanded (such as `HEAD~`, or a SHA-1) it will be -supplied as it was originally given. +although the full object name would be supplied. If the foreign ref does not +yet exist the `<remote object name>` will be the all-zeroes object name. If a +ref is to be deleted, the `<local ref>` will be supplied as `(delete)` and the +`<local object name>` will be the all-zeroes object name. If the local commit +was specified by something other than a name which could be expanded (such as +`HEAD~`, or an object name) it will be supplied as it was originally given. If this hook exits with a non-zero status, `git push` will abort without pushing anything. Information about why the push is rejected may be sent @@ -243,7 +268,7 @@ input a line of the format: where `<old-value>` is the old object name stored in the ref, `<new-value>` is the new object name to be stored in the ref and `<ref-name>` is the full name of the ref. -When creating a new ref, `<old-value>` is 40 `0`. +When creating a new ref, `<old-value>` is the all-zeroes object name. If the hook exits with non-zero status, none of the refs will be updated. If the hook exits with zero, updating of individual refs can @@ -310,6 +335,68 @@ The default 'update' hook, when enabled--and with `hooks.allowunannotated` config option unset or set to false--prevents unannotated tags to be pushed. +[[proc-receive]] +proc-receive +~~~~~~~~~~~~ + +This hook is invoked by linkgit:git-receive-pack[1]. If the server has +set the multi-valued config variable `receive.procReceiveRefs`, and the +commands sent to 'receive-pack' have matching reference names, these +commands will be executed by this hook, instead of by the internal +`execute_commands()` function. This hook is responsible for updating +the relevant references and reporting the results back to 'receive-pack'. + +This hook executes once for the receive operation. It takes no +arguments, but uses a pkt-line format protocol to communicate with +'receive-pack' to read commands, push-options and send results. In the +following example for the protocol, the letter 'S' stands for +'receive-pack' and the letter 'H' stands for this hook. + + # Version and features negotiation. + S: PKT-LINE(version=1\0push-options atomic...) + S: flush-pkt + H: PKT-LINE(version=1\0push-options...) + H: flush-pkt + + # Send commands from server to the hook. + S: PKT-LINE(<old-oid> <new-oid> <ref>) + S: ... ... + S: flush-pkt + # Send push-options only if the 'push-options' feature is enabled. + S: PKT-LINE(push-option) + S: ... ... + S: flush-pkt + + # Receive result from the hook. + # OK, run this command successfully. + H: PKT-LINE(ok <ref>) + # NO, I reject it. + H: PKT-LINE(ng <ref> <reason>) + # Fall through, let 'receive-pack' to execute it. + H: PKT-LINE(ok <ref>) + H: PKT-LINE(option fall-through) + # OK, but has an alternate reference. The alternate reference name + # and other status can be given in option directives. + H: PKT-LINE(ok <ref>) + H: PKT-LINE(option refname <refname>) + H: PKT-LINE(option old-oid <old-oid>) + H: PKT-LINE(option new-oid <new-oid>) + H: PKT-LINE(option forced-update) + H: ... ... + H: flush-pkt + +Each command for the 'proc-receive' hook may point to a pseudo-reference +and always has a zero-old as its old-oid, while the 'proc-receive' hook +may update an alternate reference and the alternate reference may exist +already with a non-zero old-oid. For this case, this hook will use +"option" directives to report extended attributes for the reference given +by the leading "ok" directive. + +The report of the commands of this hook should have the same order as +the input. The exit status of the 'proc-receive' hook only determines +the success or failure of the group of commands sent to it, unless +atomic push is in use. + [[post-receive]] post-receive ~~~~~~~~~~~~ @@ -381,6 +468,44 @@ Both standard output and standard error output are forwarded to `git send-pack` on the other end, so you can simply `echo` messages for the user. +reference-transaction +~~~~~~~~~~~~~~~~~~~~~ + +This hook is invoked by any Git command that performs reference +updates. It executes whenever a reference transaction is prepared, +committed or aborted and may thus get called multiple times. The hook +does not cover symbolic references (but that may change in the future). + +The hook takes exactly one argument, which is the current state the +given reference transaction is in: + + - "prepared": All reference updates have been queued to the + transaction and references were locked on disk. + + - "committed": The reference transaction was committed and all + references now have their respective new value. + + - "aborted": The reference transaction was aborted, no changes + were performed and the locks have been released. + +For each reference update that was added to the transaction, the hook +receives on standard input a line of the format: + + <old-value> SP <new-value> SP <ref-name> LF + +where `<old-value>` is the old object name passed into the reference +transaction, `<new-value>` is the new object name to be stored in the +ref and `<ref-name>` is the full name of the ref. When force updating +the reference regardless of its current value or when the reference is +to be created anew, `<old-value>` is the all-zeroes object name. To +distinguish these cases, you can inspect the current value of +`<ref-name>` via `git rev-parse`. + +The exit status of the hook is ignored for any state except for the +"prepared" state. In the "prepared" state, a non-zero exit status will +cause the transaction to be aborted. The hook will not be called with +"aborted" state in that case. + push-to-checkout ~~~~~~~~~~~~~~~~ @@ -406,7 +531,8 @@ exit with a zero status. For example, the hook can simply run `git read-tree -u -m HEAD "$1"` in order to emulate `git fetch` that is run in the reverse direction with `git push`, as the two-tree form of `git read-tree -u -m` is -essentially the same as `git checkout` that switches branches while +essentially the same as `git switch` or `git checkout` +that switches branches while keeping the local changes in the working tree that do not interfere with the difference between the branches. @@ -423,15 +549,17 @@ post-rewrite This hook is invoked by commands that rewrite commits (linkgit:git-commit[1] when called with `--amend` and -linkgit:git-rebase[1]; currently `git filter-branch` does 'not' call -it!). Its first argument denotes the command it was invoked by: -currently one of `amend` or `rebase`. Further command-dependent -arguments may be passed in the future. +linkgit:git-rebase[1]; however, full-history (re)writing tools like +linkgit:git-fast-import[1] or +https://github.com/newren/git-filter-repo[git-filter-repo] typically +do not call it!). Its first argument denotes the command it was +invoked by: currently one of `amend` or `rebase`. Further +command-dependent arguments may be passed in the future. The hook receives a list of the rewritten commits on stdin, in the format - <old-sha1> SP <new-sha1> [ SP <extra-info> ] LF + <old-object-name> SP <new-object-name> [ SP <extra-info> ] LF The 'extra-info' is again command-dependent. If it is empty, the preceding SP is also omitted. Currently, no commands pass any @@ -447,7 +575,7 @@ rebase:: For the 'squash' and 'fixup' operation, all commits that were squashed are listed as being rewritten to the squashed commit. This means that there will be several lines sharing the same - 'new-sha1'. + 'new-object-name'. + The commits are guaranteed to be listed in the order that they were processed by rebase. @@ -464,9 +592,16 @@ fsmonitor-watchman ~~~~~~~~~~~~~~~~~~ This hook is invoked when the configuration option `core.fsmonitor` is -set to `.git/hooks/fsmonitor-watchman`. It takes two arguments, a version -(currently 1) and the time in elapsed nanoseconds since midnight, -January 1, 1970. +set to `.git/hooks/fsmonitor-watchman` or `.git/hooks/fsmonitor-watchmanv2` +depending on the version of the hook to use. + +Version 1 takes two arguments, a version (1) and the time in elapsed +nanoseconds since midnight, January 1, 1970. + +Version 2 takes two arguments, a version (2) and a token that is used +for identifying changes since the token. For watchman this would be +a clock id. This version must output to stdout the new token followed +by a NUL before the list of files. The hook should output to stdout the list of all files in the working directory that may have changed since the requested time. The logic @@ -489,12 +624,61 @@ The exit status determines whether git will use the data from the hook to limit its search. On error, it will fall back to verifying all files and folders. +p4-changelist +~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-changelist` hook is executed after the changelist +message has been edited by the user. It can be bypassed with the +`--no-verify` option. It takes a single parameter, the name +of the file that holds the proposed changelist text. Exiting +with a non-zero status causes the command to abort. + +The hook is allowed to edit the changelist file and can be used +to normalize the text into some project standard format. It can +also be used to refuse the Submit after inspect the message file. + +Run `git-p4 submit --help` for details. + +p4-prepare-changelist +~~~~~~~~~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-prepare-changelist` hook is executed right after preparing +the default changelist message and before the editor is started. +It takes one parameter, the name of the file that contains the +changelist text. Exiting with a non-zero status from the script +will abort the process. + +The purpose of the hook is to edit the message file in place, +and it is not suppressed by the `--no-verify` option. This hook +is called even if `--prepare-p4-only` is set. + +Run `git-p4 submit --help` for details. + +p4-post-changelist +~~~~~~~~~~~~~~~~~~ + +This hook is invoked by `git-p4 submit`. + +The `p4-post-changelist` hook is invoked after the submit has +successfully occurred in P4. It takes no parameters and is meant +primarily for notification and cannot affect the outcome of the +git p4 submit action. + +Run `git-p4 submit --help` for details. + p4-pre-submit ~~~~~~~~~~~~~ This hook is invoked by `git-p4 submit`. It takes no parameters and nothing from standard input. Exiting with non-zero status from this script prevent -`git-p4 submit` from launching. Run `git-p4 submit --help` for details. +`git-p4 submit` from launching. It can be bypassed with the `--no-verify` +command line option. Run `git-p4 submit --help` for details. + + post-index-change ~~~~~~~~~~~~~~~~~ diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt index d47b1ae296..f8a1fc2014 100644 --- a/Documentation/gitignore.txt +++ b/Documentation/gitignore.txt @@ -27,12 +27,11 @@ precedence, the last matching pattern decides the outcome): them. * Patterns read from a `.gitignore` file in the same directory - as the path, or in any parent directory, with patterns in the - higher level files (up to the toplevel of the work tree) being overridden - by those in lower level files down to the directory containing the file. - These patterns match relative to the location of the - `.gitignore` file. A project normally includes such - `.gitignore` files in its repository, containing patterns for + as the path, or in any parent directory (up to the top-level of the working + tree), with patterns in the higher level files being overridden by those in + lower level files down to the directory containing the file. These patterns + match relative to the location of the `.gitignore` file. A project normally + includes such `.gitignore` files in its repository, containing patterns for files generated as part of the project build. * Patterns read from `$GIT_DIR/info/exclude`. @@ -149,11 +148,15 @@ not tracked by Git remain untracked. To stop tracking a file that is currently tracked, use 'git rm --cached'. +Git does not follow symbolic links when accessing a `.gitignore` file in +the working tree. This keeps behavior consistent when the file is +accessed from the index or a tree versus from the filesystem. + EXAMPLES -------- - The pattern `hello.*` matches any file or folder - whose name begins with `hello`. If one wants to restrict + whose name begins with `hello.`. If one wants to restrict this only to the directory and not in its subdirectories, one can prepend the pattern with a slash, i.e. `/hello.*`; the pattern now matches `hello.txt`, `hello.c` but not diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt index 1eabb0aaf3..d50e9ed10e 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.txt @@ -98,21 +98,7 @@ linkgit:git-rev-list[1] for a complete list. (See "History simplification" in linkgit:git-log[1] for a more detailed explanation.) --L<start>,<end>:<file>:: --L:<funcname>:<file>:: - - Trace the evolution of the line range given by "<start>,<end>" - (or the function name regex <funcname>) within the <file>. You may - not give any pathspec limiters. This is currently limited to - a walk starting from a single revision, i.e., you may only - give zero or one positive revision arguments. - You can specify this option more than once. -+ -*Note:* gitk (unlike linkgit:git-log[1]) currently only understands -this option if you specify it "glued together" with its argument. Do -*not* put a space after `-L`. -+ -include::line-range-format.txt[] +include::line-range-options.txt[] <revision range>:: diff --git a/Documentation/gitmailmap.txt b/Documentation/gitmailmap.txt new file mode 100644 index 0000000000..06f4af93fe --- /dev/null +++ b/Documentation/gitmailmap.txt @@ -0,0 +1,130 @@ +gitmailmap(5) +============= + +NAME +---- +gitmailmap - Map author/committer names and/or E-Mail addresses + +SYNOPSIS +-------- +$GIT_WORK_TREE/.mailmap + + +DESCRIPTION +----------- + +If the file `.mailmap` exists at the toplevel of the repository, or at +the location pointed to by the `mailmap.file` or `mailmap.blob` +configuration options (see linkgit:git-config[1]), it +is used to map author and committer names and email addresses to +canonical real names and email addresses. + + +SYNTAX +------ + +The '#' character begins a comment to the end of line, blank lines +are ignored. + +In the simple form, each line in the file consists of the canonical +real name of an author, whitespace, and an email address used in the +commit (enclosed by '<' and '>') to map to the name. For example: +-- + Proper Name <commit@email.xx> +-- + +The more complex forms are: +-- + <proper@email.xx> <commit@email.xx> +-- +which allows mailmap to replace only the email part of a commit, and: +-- + Proper Name <proper@email.xx> <commit@email.xx> +-- +which allows mailmap to replace both the name and the email of a +commit matching the specified commit email address, and: +-- + Proper Name <proper@email.xx> Commit Name <commit@email.xx> +-- +which allows mailmap to replace both the name and the email of a +commit matching both the specified commit name and email address. + +Both E-Mails and names are matched case-insensitively. For example +this would also match the 'Commit Name <commit@email.xx>' above: +-- + Proper Name <proper@email.xx> CoMmIt NaMe <CoMmIt@EmAiL.xX> +-- + +NOTES +----- + +Git does not follow symbolic links when accessing a `.mailmap` file in +the working tree. This keeps behavior consistent when the file is +accessed from the index or a tree versus from the filesystem. + +EXAMPLES +-------- + +Your history contains commits by two authors, Jane +and Joe, whose names appear in the repository under several forms: + +------------ +Joe Developer <joe@example.com> +Joe R. Developer <joe@example.com> +Jane Doe <jane@example.com> +Jane Doe <jane@laptop.(none)> +Jane D. <jane@desktop.(none)> +------------ + +Now suppose that Joe wants his middle name initial used, and Jane +prefers her family name fully spelled out. A `.mailmap` file to +correct the names would look like: + +------------ +Joe R. Developer <joe@example.com> +Jane Doe <jane@example.com> +Jane Doe <jane@desktop.(none)> +------------ + +Note that there's no need to map the name for '<jane@laptop.(none)>' to +only correct the names. However, leaving the obviously broken +'<jane@laptop.(none)>' and '<jane@desktop.(none)>' E-Mails as-is is +usually not what you want. A `.mailmap` file which also corrects those +is: + +------------ +Joe R. Developer <joe@example.com> +Jane Doe <jane@example.com> <jane@laptop.(none)> +Jane Doe <jane@example.com> <jane@desktop.(none)> +------------ + +Finally, let's say that Joe and Jane shared an E-Mail address, but not +a name, e.g. by having these two commits in the history generated by a +bug reporting system. I.e. names appearing in history as: + +------------ +Joe <bugs@example.com> +Jane <bugs@example.com> +------------ + +A full `.mailmap` file which also handles those cases (an addition of +two lines to the above example) would be: + +------------ +Joe R. Developer <joe@example.com> +Jane Doe <jane@example.com> <jane@laptop.(none)> +Jane Doe <jane@example.com> <jane@desktop.(none)> +Joe R. Developer <joe@example.com> Joe <bugs@example.com> +Jane Doe <jane@example.com> Jane <bugs@example.com> +------------ + + + +SEE ALSO +-------- +linkgit:git-check-mailmap[1] + + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt index f260b55f3a..dcee09b500 100644 --- a/Documentation/gitmodules.txt +++ b/Documentation/gitmodules.txt @@ -7,7 +7,7 @@ gitmodules - Defining submodule properties SYNOPSIS -------- -$GIT_WORK_DIR/.gitmodules +$GIT_WORK_TREE/.gitmodules DESCRIPTION @@ -27,19 +27,19 @@ submodule.<name>.path:: Defines the path, relative to the top-level directory of the Git working tree, where the submodule is expected to be checked out. The path name must not end with a `/`. All submodule paths must - be unique within the .gitmodules file. + be unique within the `.gitmodules` file. submodule.<name>.url:: Defines a URL from which the submodule repository can be cloned. This may be either an absolute URL ready to be passed to - linkgit:git-clone[1] or (if it begins with ./ or ../) a location + linkgit:git-clone[1] or (if it begins with `./` or `../`) a location relative to the superproject's origin repository. In addition, there are a number of optional keys: submodule.<name>.update:: Defines the default update procedure for the named submodule, - i.e. how the submodule is updated by "git submodule update" + i.e. how the submodule is updated by the `git submodule update` command in the superproject. This is only used by `git submodule init` to initialize the configuration variable of the same name. Allowed values here are 'checkout', 'rebase', @@ -49,22 +49,22 @@ submodule.<name>.update:: submodule.<name>.branch:: A remote branch name for tracking updates in the upstream submodule. - If the option is not specified, it defaults to 'master'. A special - value of `.` is used to indicate that the name of the branch in the - submodule should be the same name as the current branch in the + If the option is not specified, it defaults to the remote `HEAD`. + A special value of `.` is used to indicate that the name of the branch + in the submodule should be the same name as the current branch in the current repository. See the `--remote` documentation in linkgit:git-submodule[1] for details. submodule.<name>.fetchRecurseSubmodules:: This option can be used to control recursive fetching of this - submodule. If this option is also present in the submodules entry in - .git/config of the superproject, the setting there will override the - one found in .gitmodules. + submodule. If this option is also present in the submodule's entry in + `.git/config` of the superproject, the setting there will override the + one found in `.gitmodules`. Both settings can be overridden on the command line by using the - "--[no-]recurse-submodules" option to "git fetch" and "git pull". + `--[no-]recurse-submodules` option to `git fetch` and `git pull`. submodule.<name>.ignore:: - Defines under what circumstances "git status" and the diff family show + Defines under what circumstances `git status` and the diff family show a submodule as modified. The following values are supported: + -- @@ -73,23 +73,23 @@ submodule.<name>.ignore:: been staged). dirty;; All changes to the submodule's work tree will be ignored, only - committed differences between the HEAD of the submodule and its + committed differences between the `HEAD` of the submodule and its recorded state in the superproject are taken into account. untracked;; Only untracked files in submodules will be ignored. Committed differences and modifications to tracked files will show up. - none;; No modifiations to submodules are ignored, all of committed + none;; No modifications to submodules are ignored, all of committed differences, and modifications to tracked and untracked files are shown. This is the default option. -If this option is also present in the submodules entry in .git/config +If this option is also present in the submodule's entry in `.git/config` of the superproject, the setting there will override the one found in -.gitmodules. +`.gitmodules`. Both settings can be overridden on the command line by using the -"--ignore-submodule" option. The 'git submodule' commands are not +`--ignore-submodules` option. The `git submodule` commands are not affected by this setting. -- @@ -98,20 +98,29 @@ submodule.<name>.shallow:: shallow clone (with a history depth of 1) unless the user explicitly asks for a non-shallow clone. +NOTES +----- + +Git does not allow the `.gitmodules` file within a working tree to be a +symbolic link, and will refuse to check out such a tree entry. This +keeps behavior consistent when the file is accessed from the index or a +tree versus from the filesystem, and helps Git reliably enforce security +checks of the file contents. EXAMPLES -------- -Consider the following .gitmodules file: - - [submodule "libfoo"] - path = include/foo - url = git://foo.com/git/lib.git +Consider the following `.gitmodules` file: - [submodule "libbar"] - path = include/bar - url = git://bar.com/git/lib.git +---- +[submodule "libfoo"] + path = include/foo + url = git://foo.com/git/lib.git +[submodule "libbar"] + path = include/bar + url = git://bar.com/git/lib.git +---- This defines two submodules, `libfoo` and `libbar`. These are expected to be checked out in the paths `include/foo` and `include/bar`, and for both @@ -119,7 +128,7 @@ submodules a URL is specified which can be used for cloning the submodules. SEE ALSO -------- -linkgit:git-submodule[1] linkgit:git-config[1] +linkgit:git-submodule[1], linkgit:gitsubmodules[7], linkgit:git-config[1] GIT --- diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt index b614969ad2..1c8d2ecc35 100644 --- a/Documentation/gitnamespaces.txt +++ b/Documentation/gitnamespaces.txt @@ -62,3 +62,7 @@ git clone ext::'git --namespace=foo %s /tmp/prefixed.git' ---------- include::transfer-data-leaks.txt[] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 43f80c8068..6f1e269ae4 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -238,6 +238,9 @@ the remote repository. `--signed-tags=verbatim` to linkgit:git-fast-export[1]. In the absence of this capability, Git will use `--signed-tags=warn-strip`. +'object-format':: + This indicates that the helper is able to interact with the remote + side using an explicit hash algorithm extension. COMMANDS @@ -257,12 +260,14 @@ Support for this command is mandatory. 'list':: Lists the refs, one per line, in the format "<value> <name> [<attr> ...]". The value may be a hex sha1 hash, "@<dest>" for - a symref, or "?" to indicate that the helper could not get the - value of the ref. A space-separated list of attributes follows - the name; unrecognized attributes are ignored. The list ends - with a blank line. + a symref, ":<keyword> <value>" for a key-value pair, or + "?" to indicate that the helper could not get the value of the + ref. A space-separated list of attributes follows the name; + unrecognized attributes are ignored. The list ends with a + blank line. + See REF LIST ATTRIBUTES for a list of currently defined attributes. +See REF LIST KEYWORDS for a list of currently defined keywords. + Supported if the helper has the "fetch" or "import" capability. @@ -297,9 +302,13 @@ Supported if the helper has the "option" capability. same batch are complete. Only objects which were reported in the output of 'list' with a sha1 may be fetched this way. + -Optionally may output a 'lock <file>' line indicating a file under -GIT_DIR/objects/pack which is keeping a pack until refs can be -suitably updated. +Optionally may output a 'lock <file>' line indicating the full path of +a file under `$GIT_DIR/objects/pack` which is keeping a pack until +refs can be suitably updated. The path must end with `.keep`. This is +a mechanism to name a <pack,idx,keep> tuple by giving only the keep +component. The kept pack will not be deleted by a concurrent repack, +even though its objects may not be referenced until the fetch completes. +The `.keep` file will be deleted at the conclusion of the fetch. + If option 'check-connectivity' is requested, the helper must output 'connectivity-ok' if the clone is self-contained and connected. @@ -401,7 +410,9 @@ Supported if the helper has the "connect" capability. trying to fall back). After line feed terminating the positive (empty) response, the output of the service starts. Messages (both request and response) must consist of zero or more - PKT-LINEs, terminating in a flush packet. The client must not + PKT-LINEs, terminating in a flush packet. Response messages will + then have a response end packet after the flush packet to + indicate the end of a response. The client must not expect the server to store any state in between request-response pairs. After the connection ends, the remote helper exits. + @@ -426,6 +437,18 @@ attributes are defined. This ref is unchanged since the last import or fetch, although the helper cannot necessarily determine what value that produced. +REF LIST KEYWORDS +----------------- + +The 'list' command may produce a list of key-value pairs. +The following keys are defined. + +'object-format':: + The refs are using the given hash algorithm. This keyword is only + used if the server and client both support the object-format + extension. + + OPTIONS ------- @@ -505,6 +528,19 @@ set by Git if the remote helper has the 'option' capability. Indicate that only the objects wanted need to be fetched, not their dependents. +'option atomic' {'true'|'false'}:: + When pushing, request the remote server to update refs in a single atomic + transaction. If successful, all refs will be updated, or none will. If the + remote side does not support this capability, the push will fail. + +'option object-format' {'true'|algorithm}:: + If 'true', indicate that the caller wants hash algorithm information + to be passed back from the remote. This mode is used when fetching + refs. ++ +If set to an algorithm, indicate that the caller wants to interact with +the remote side using that algorithm. + SEE ALSO -------- linkgit:git-remote[1] diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index 216b11ee88..1a2ef4c150 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -59,7 +59,7 @@ objects/[0-9a-f][0-9a-f]:: here are often called 'unpacked' (or 'loose') objects. objects/pack:: - Packs (files that store many object in compressed form, + Packs (files that store many objects in compressed form, along with index files to allow them to be randomly accessed) are found in this directory. @@ -96,9 +96,9 @@ refs:: directory. The 'git prune' command knows to preserve objects reachable from refs found in this directory and its subdirectories. - This directory is ignored (except refs/bisect and - refs/worktree) if $GIT_COMMON_DIR is set and - "$GIT_COMMON_DIR/refs" will be used instead. + This directory is ignored (except refs/bisect, + refs/rewritten and refs/worktree) if $GIT_COMMON_DIR is + set and "$GIT_COMMON_DIR/refs" will be used instead. refs/heads/`name`:: records tip-of-the-tree commit objects of branch `name` @@ -240,8 +240,8 @@ remotes:: logs:: Records of changes made to refs are stored in this directory. See linkgit:git-update-ref[1] for more information. This - directory is ignored if $GIT_COMMON_DIR is set and - "$GIT_COMMON_DIR/logs" will be used instead. + directory is ignored (except logs/HEAD) if $GIT_COMMON_DIR is + set and "$GIT_COMMON_DIR/logs" will be used instead. logs/refs/heads/`name`:: Records all changes made to the branch tip named `name`. diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt index 0a890205b8..891c8da4fd 100644 --- a/Documentation/gitsubmodules.txt +++ b/Documentation/gitsubmodules.txt @@ -3,7 +3,7 @@ gitsubmodules(7) NAME ---- -gitsubmodules - mounting one repository inside another +gitsubmodules - Mounting one repository inside another SYNOPSIS -------- @@ -225,10 +225,10 @@ presence of the .url field. Workflow for a third party library ---------------------------------- - # add a submodule + # Add a submodule git submodule add <url> <path> - # occasionally update the submodule to a new version: + # Occasionally update the submodule to a new version: git -C <path> checkout <new version> git add <path> git commit -m "update submodule to new version" @@ -246,20 +246,23 @@ Workflow for an artificially split repo # regular commands recurse into submodules by default git config --global submodule.recurse true - # Unlike the other commands below clone still needs + # Unlike most other commands below, clone still needs # its own recurse flag: git clone --recurse <URL> <directory> cd <directory> # Get to know the code: git grep foo - git ls-files + git ls-files --recurse-submodules + +[NOTE] +`git ls-files` also requires its own `--recurse-submodules` flag. # Get new code git fetch git pull --rebase - # change worktree + # Change worktree git checkout git reset @@ -267,11 +270,12 @@ Implementation details ---------------------- When cloning or pulling a repository containing submodules the submodules -will not be checked out by default; You can instruct 'clone' to recurse -into submodules. The 'init' and 'update' subcommands of 'git submodule' +will not be checked out by default; you can instruct `clone` to recurse +into submodules. The `init` and `update` subcommands of `git submodule` will maintain submodules checked out and at an appropriate revision in -your working tree. Alternatively you can set 'submodule.recurse' to have -'checkout' recursing into submodules. +your working tree. Alternatively you can set `submodule.recurse` to have +`checkout` recursing into submodules (note that `submodule.recurse` also +affects other Git commands, see linkgit:git-config[1] for a complete list). SEE ALSO diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.txt index e0976f6017..8bdb7d0bd3 100644 --- a/Documentation/gittutorial-2.txt +++ b/Documentation/gittutorial-2.txt @@ -370,13 +370,13 @@ situation: $ git status On branch master Changes to be committed: - (use "git reset HEAD <file>..." to unstage) + (use "git restore --staged <file>..." to unstage) new file: closing.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) - (use "git checkout -- <file>..." to discard changes in working directory) + (use "git restore <file>..." to discard changes in working directory) modified: file.txt diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt index 242de31cb6..0e0b863105 100644 --- a/Documentation/gittutorial.txt +++ b/Documentation/gittutorial.txt @@ -110,7 +110,7 @@ $ git status On branch master Changes to be committed: Your branch is up to date with 'origin/master'. - (use "git reset HEAD <file>..." to unstage) + (use "git restore --staged <file>..." to unstage) modified: file1 modified: file2 @@ -207,7 +207,7 @@ automatically. The asterisk marks the branch you are currently on; type ------------------------------------------------ -$ git checkout experimental +$ git switch experimental ------------------------------------------------ to switch to the experimental branch. Now edit a file, commit the @@ -216,7 +216,7 @@ change, and switch back to the master branch: ------------------------------------------------ (edit file) $ git commit -a -$ git checkout master +$ git switch master ------------------------------------------------ Check that the change you made is no longer visible, since it was @@ -322,7 +322,7 @@ initiating this "pull". If Bob's work conflicts with what Alice did since their histories forked, Alice will use her working tree and the index to resolve conflicts, and existing local changes will interfere with the conflict resolution process (Git will still perform the fetch but will -refuse to merge --- Alice will have to get rid of her local changes in +refuse to merge -- Alice will have to get rid of her local changes in some way and pull again when this happens). Alice can peek at what Bob did without merging first, using the "fetch" diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.txt index 35317e71c8..34b1d6e224 100644 --- a/Documentation/gitweb.conf.txt +++ b/Documentation/gitweb.conf.txt @@ -751,6 +751,17 @@ default font sizes or lineheights are changed (e.g. via adding extra CSS stylesheet in `@stylesheets`), it may be appropriate to change these values. +email-privacy:: + Redact e-mail addresses from the generated HTML, etc. content. + This obscures e-mail addresses retrieved from the author/committer + and comment sections of the Git log. + It is meant to hinder web crawlers that harvest and abuse addresses. + Such crawlers may not respect robots.txt. + Note that users and user tools also see the addresses as redacted. + If Gitweb is not the final step in a workflow then subsequent steps + may misbehave because of the redacted information they receive. + Disabled by default. + highlight:: Server-side syntax highlight support in "blob" view. It requires `$highlight_bin` program to be available (see the description of @@ -786,9 +797,9 @@ forks:: subdirectories of project root (basename) to be forks of existing projects. For each project +$projname.git+, projects in the +$projname/+ directory and its subdirectories will not be - shown in the main projects list. Instead, a \'\+' mark is shown - next to +$projname+, which links to a "forks" view that lists all - the forks (all projects in +$projname/+ subdirectory). Additionally + shown in the main projects list. Instead, a \'+' mark is shown + next to `$projname`, which links to a "forks" view that lists all + the forks (all projects in `$projname/` subdirectory). Additionally a "forks" view for a project is linked from project summary page. + If the project list is taken from a file (+$projects_list+ points to a diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.txt index ca11c7bdaf..47cf97f9be 100644 --- a/Documentation/gitworkflows.txt +++ b/Documentation/gitworkflows.txt @@ -85,15 +85,15 @@ As a given feature goes from experimental to stable, it also There is a fourth official branch that is used slightly differently: -* 'pu' (proposed updates) is an integration branch for things that are - not quite ready for inclusion yet (see "Integration Branches" - below). +* 'seen' (patches seen by the maintainer) is an integration branch for + things that are not quite ready for inclusion yet (see "Integration + Branches" below). Each of the four branches is usually a direct descendant of the one above it. Conceptually, the feature enters at an unstable branch (usually 'next' -or 'pu'), and "graduates" to 'master' for the next release once it is +or 'seen'), and "graduates" to 'master' for the next release once it is considered stable enough. @@ -207,7 +207,7 @@ If you make it (very) clear that this branch is going to be deleted right after the testing, you can even publish this branch, for example to give the testers a chance to work with it, or other developers a chance to see if their in-progress work will be compatible. `git.git` -has such an official throw-away integration branch called 'pu'. +has such an official throw-away integration branch called 'seen'. Branch management for a release @@ -291,8 +291,8 @@ This will not happen if the content of the branches was verified as described in the previous section. -Branch management for next and pu after a feature release -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Branch management for next and seen after a feature release +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ After a feature release, the integration branch 'next' may optionally be rewound and rebuilt from the tip of 'master' using the surviving @@ -301,8 +301,7 @@ topics on 'next': .Rewind and rebuild next [caption="Recipe: "] ===================================== -* `git checkout next` -* `git reset --hard master` +* `git switch -C next master` * `git merge ai/topic_in_next1` * `git merge ai/topic_in_next2` * ... @@ -320,8 +319,8 @@ so. If you do this, then you should make a public announcement indicating that 'next' was rewound and rebuilt. -The same rewind and rebuild process may be followed for 'pu'. A public -announcement is not necessary since 'pu' is a throw-away branch, as +The same rewind and rebuild process may be followed for 'seen'. A public +announcement is not necessary since 'seen' is a throw-away branch, as described above. diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index 8d38ae6010..c077971335 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -18,7 +18,7 @@ Untyped <<def_object,object>>, e.g. the contents of a file. [[def_branch]]branch:: - A "branch" is an active line of development. The most recent + A "branch" is a line of development. The most recent <<def_commit,commit>> on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch <<def_head,head>>, which moves forward as additional development @@ -146,8 +146,8 @@ current branch integrates with) obviously do not work, as there is no <<def_revision,revision>> and you are "merging" another <<def_branch,branch>>'s changes that happen to be a descendant of what you have. In such a case, you do not make a new <<def_merge,merge>> - <<def_commit,commit>> but instead just update to his - revision. This will happen frequently on a + <<def_commit,commit>> but instead just update your branch to point at the same + revision as the branch you are merging. This will happen frequently on a <<def_remote_tracking_branch,remote-tracking branch>> of a remote <<def_repository,repository>>. @@ -255,7 +255,7 @@ This commit is referred to as a "merge commit", or sometimes just a [[def_object]]object:: The unit of storage in Git. It is uniquely identified by the <<def_SHA1,SHA-1>> of its contents. Consequently, an - object can not be changed. + object cannot be changed. [[def_object_database]]object database:: Stores a set of "objects", and an individual <<def_object,object>> is diff --git a/Documentation/howto/coordinate-embargoed-releases.txt b/Documentation/howto/coordinate-embargoed-releases.txt new file mode 100644 index 0000000000..601aae88e9 --- /dev/null +++ b/Documentation/howto/coordinate-embargoed-releases.txt @@ -0,0 +1,131 @@ +Content-type: text/asciidoc +Abstract: When a critical vulnerability is discovered and fixed, we follow this + script to coordinate a public release. + +How we coordinate embargoed releases +==================================== + +To protect Git users from critical vulnerabilities, we do not just release +fixed versions like regular maintenance releases. Instead, we coordinate +releases with packagers, keeping the fixes under an embargo until the release +date. That way, users will have a chance to upgrade on that date, no matter +what Operating System or distribution they run. + +Open a Security Advisory draft +------------------------------ + +The first step is to https://github.com/git/git/security/advisories/new[open an +advisory]. Technically, it is not necessary, but it is convenient and saves a +bit of hassle. This advisory can also be used to obtain the CVE number and it +will give us a private fork associated with it that can be used to collaborate +on a fix. + +Release date of the embargoed version +------------------------------------- + +If the vulnerability affects Windows users, we want to have our friends over at +Visual Studio on board. This means we need to target a "Patch Tuesday" (i.e. a +second Tuesday of the month), at the minimum three weeks from heads-up to +coordinated release. + +If the vulnerability affects the server side, or can benefit from scans on the +server side (i.e. if `git fsck` can detect an attack), it is important to give +all involved Git repository hosting sites enough time to scan all of those +repositories. + +Notifying the Linux distributions +--------------------------------- + +At most two weeks before release date, we need to send a notification to +distros@vs.openwall.org, preferably less than 7 days before the release date. +This will reach most (all?) Linux distributions. See an example below, and the +guidelines for this mailing list at +https://oss-security.openwall.org/wiki/mailing-lists/distros#how-to-use-the-lists[here]. + +Once the version has been published, we send a note about that to oss-security. +As an example, see https://www.openwall.com/lists/oss-security/2019/12/13/1[the +v2.24.1 mail]; +https://oss-security.openwall.org/wiki/mailing-lists/oss-security[Here] are +their guidelines. + +The mail to oss-security should also describe the exploit, and give credit to +the reporter(s): security researchers still receive too little respect for the +invaluable service they provide, and public credit goes a long way to keep them +paid by their respective organizations. + +Technically, describing any exploit can be delayed up to 7 days, but we usually +refrain from doing that, including it right away. + +As a courtesy we typically attach a Git bundle (as `.tar.xz` because the list +will drop `.bundle` attachments) in the mail to distros@ so that the involved +parties can take care of integrating/backporting them. This bundle is typically +created using a command like this: + + git bundle create cve-xxx.bundle ^origin/master vA.B.C vD.E.F + tar cJvf cve-xxx.bundle.tar.xz cve-xxx.bundle + +Example mail to distros@vs.openwall.org +--------------------------------------- + +.... +To: distros@vs.openwall.org +Cc: git-security@googlegroups.com, <other people involved in the report/fix> +Subject: [vs] Upcoming Git security fix release + +Team, + +The Git project will release new versions on <date> at 10am Pacific Time or +soon thereafter. I have attached a Git bundle (embedded in a `.tar.xz` to avoid +it being dropped) which you can fetch into a clone of +https://github.com/git/git via `git fetch --tags /path/to/cve-xxx.bundle`, +containing the tags for versions <versions>. + +You can verify with `git tag -v <tag>` that the versions were signed by +the Git maintainer, using the same GPG key as e.g. v2.24.0. + +Please use these tags to prepare `git` packages for your various +distributions, using the appropriate tagged versions. The added test cases +help verify the correctness. + +The addressed issues are: + +<list of CVEs with a short description, typically copy/pasted from Git's +release notes, usually demo exploit(s), too> + +Credit for finding the vulnerability goes to <reporter>, credit for fixing +it goes to <developer>. + +Thanks, +<name> + +.... + +Example mail to oss-security@lists.openwall.com +----------------------------------------------- + +.... +To: oss-security@lists.openwall.com +Cc: git-security@googlegroups.com, <other people involved in the report/fix> +Subject: git: <copy from security advisory> + +Team, + +The Git project released new versions on <date>, addressing <CVE>. + +All supported platforms are affected in one way or another, and all Git +versions all the way back to <version> are affected. The fixed versions are: +<versions>. + +Link to the announcement: <link to lore.kernel.org/git> + +We highly recommend to upgrade. + +The addressed issues are: +* <list of CVEs and their explanations, along with demo exploits> + +Credit for finding the vulnerability goes to <reporter>, credit for fixing +it goes to <developer>. + +Thanks, +<name> +.... diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt index ca4378740c..a67130debb 100644 --- a/Documentation/howto/maintain-git.txt +++ b/Documentation/howto/maintain-git.txt @@ -66,7 +66,7 @@ this mailing list after each feature release is made. demonstrated to be regression free. New changes are tested in 'next' before merged to 'master'. - - 'pu' branch is used to publish other proposed changes that do + - 'seen' branch is used to publish other proposed changes that do not yet pass the criteria set for 'next'. - The tips of 'master' and 'maint' branches will not be rewound to @@ -76,7 +76,7 @@ this mailing list after each feature release is made. of the cycle. - Usually 'master' contains all of 'maint' and 'next' contains all - of 'master'. 'pu' contains all the topics merged to 'next', but + of 'master'. 'seen' contains all the topics merged to 'next', but is rebuilt directly on 'master'. - The tip of 'master' is meant to be more stable than any @@ -154,15 +154,17 @@ by doing the following: - Anything unobvious that is applicable to 'master' (in other words, does not depend on anything that is still in 'next' and not in 'master') is applied to a new topic branch that - is forked from the tip of 'master'. This includes both + is forked from the tip of 'master' (or the last feature release, + which is a bit older than 'master'). This includes both enhancements and unobvious fixes to 'master'. A topic branch is named as ai/topic where "ai" is two-letter string named after author's initial and "topic" is a descriptive name of the topic (in other words, "what's the series is about"). - An unobvious fix meant for 'maint' is applied to a new - topic branch that is forked from the tip of 'maint'. The - topic is named as ai/maint-topic. + topic branch that is forked from the tip of 'maint' (or the + oldest and still relevant maintenance branch). The + topic may be named as ai/maint-topic. - Changes that pertain to an existing topic are applied to the branch, but: @@ -174,24 +176,40 @@ by doing the following: - Replacement patches to an existing topic are accepted only for commits not in 'next'. - The above except the "replacement" are all done with: + The initial round is done with: $ git checkout ai/topic ;# or "git checkout -b ai/topic master" $ git am -sc3 mailbox - while patch replacement is often done by: + and replacing an existing topic with subsequent round is done with: - $ git format-patch ai/topic~$n..ai/topic ;# export existing + $ git checkout master...ai/topic ;# try to reapply to the same base + $ git am -sc3 mailbox + + to prepare the new round on a detached HEAD, and then + + $ git range-diff @{-1}... + $ git diff @{-1} - then replace some parts with the new patch, and reapplying: + to double check what changed since the last round, and finally - $ git checkout ai/topic - $ git reset --hard ai/topic~$n - $ git am -sc3 -s 000*.txt + $ git checkout -B @{-1} + + to conclude (the last step is why a topic already in 'next' is + not replaced but updated incrementally). + + Whether it is the initial round or a subsequent round, the topic + may not build even in isolation, or may break the build when + merged to integration branches due to bugs. There may already + be obvious and trivial improvements suggested on the list. The + maintainer often adds an extra commit, with "SQUASH???" in its + title, to fix things up, before publishing the integration + branches to make it usable by other developers for testing. + These changes are what the maintainer is not 100% committed to + (trivial typofixes etc. are often squashed directly into the + patches that need fixing, without being applied as a separate + "SQUASH???" commit), so that they can be removed easily as needed. - The full test suite is always run for 'maint' and 'master' - after patch application; for topic branches the tests are run - as time permits. - Merge maint to master as needed: @@ -211,12 +229,12 @@ by doing the following: series?) - Prepare 'jch' branch, which is used to represent somewhere - between 'master' and 'pu' and often is slightly ahead of 'next'. + between 'master' and 'seen' and often is slightly ahead of 'next'. - $ Meta/Reintegrate master..pu >Meta/redo-jch.sh + $ Meta/Reintegrate master..seen >Meta/redo-jch.sh The result is a script that lists topics to be merged in order to - rebuild 'pu' as the input to Meta/Reintegrate script. Remove + rebuild 'seen' as the input to Meta/Reintegrate script. Remove later topics that should not be in 'jch' yet. Add a line that consists of '### match next' before the name of the first topic in the output that should be in 'jch' but not in 'next' yet. @@ -273,29 +291,29 @@ by doing the following: merged to 'master'. This may lose '### match next' marker; add it again to the appropriate place when it happens. - - Rebuild 'pu'. + - Rebuild 'seen'. - $ Meta/Reintegrate master..pu >Meta/redo-pu.sh + $ Meta/Reintegrate master..seen >Meta/redo-seen.sh - Edit the result by adding new topics that are not still in 'pu' + Edit the result by adding new topics that are not still in 'seen' in the script. Then - $ git checkout -B pu jch - $ sh Meta/redo-pu.sh + $ git checkout -B seen jch + $ sh Meta/redo-seen.sh - When all is well, clean up the redo-pu.sh script with + When all is well, clean up the redo-seen.sh script with - $ sh Meta/redo-pu.sh -u + $ sh Meta/redo-seen.sh -u Double check by running - $ git branch --no-merged pu + $ git branch --no-merged seen to see there is no unexpected leftover topics. At this point, build-test the result for semantic conflicts, and if there are, prepare an appropriate merge-fix first (see - appendix), and rebuild the 'pu' branch from scratch, starting at + appendix), and rebuild the 'seen' branch from scratch, starting at the tip of 'jch'. - Update "What's cooking" message to review the updates to @@ -305,14 +323,14 @@ by doing the following: $ Meta/cook - This script inspects the history between master..pu, finds tips + This script inspects the history between master..seen, finds tips of topic branches, compares what it found with the current contents in Meta/whats-cooking.txt, and updates that file. - Topics not listed in the file but are found in master..pu are + Topics not listed in the file but are found in master..seen are added to the "New topics" section, topics listed in the file that - are no longer found in master..pu are moved to the "Graduated to + are no longer found in master..seen are moved to the "Graduated to master" section, and topics whose commits changed their states - (e.g. used to be only in 'pu', now merged to 'next') are updated + (e.g. used to be only in 'seen', now merged to 'next') are updated with change markers "<<" and ">>". Look for lines enclosed in "<<" and ">>"; they hold contents from @@ -342,7 +360,7 @@ Observations Some observations to be made. * Each topic is tested individually, and also together with other - topics cooking first in 'pu', then in 'jch' and then in 'next'. + topics cooking first in 'seen', then in 'jch' and then in 'next'. Until it matures, no part of it is merged to 'master'. * A topic already in 'next' can get fixes while still in @@ -371,6 +389,14 @@ Some observations to be made. be included in the next feature release. Being in the 'master' branch typically is. + * Due to the nature of "SQUASH???" fix-ups, if the original author + agrees with the suggested changes, it is OK to squash them to + appropriate patches in the next round (when the suggested change + is small enough, the author should not even bother with + "Helped-by"). It is also OK to drop them from the next round + when the original author does not agree with the suggestion, but + the author is expected to say why somewhere in the discussion. + Appendix -------- @@ -385,7 +411,7 @@ new use of the variable under its old name. When these two topics are merged together, the reference to the variable newly added by the latter topic will still use the old name in the result. -The Meta/Reintegrate script that is used by redo-jch and redo-pu +The Meta/Reintegrate script that is used by redo-jch and redo-seen scripts implements a crude but usable way to work this issue around. When the script merges branch $X, it checks if "refs/merge-fix/$X" exists, and if so, the effect of it is squashed into the result of @@ -405,14 +431,14 @@ commit that can be squashed into a result of mechanical merge to correct semantic conflicts. After finding that the result of merging branch "ai/topic" to an -integration branch had such a semantic conflict, say pu~4, check the +integration branch had such a semantic conflict, say seen~4, check the problematic merge out on a detached HEAD, edit the working tree to fix the semantic conflict, and make a separate commit to record the fix-up: - $ git checkout pu~4 + $ git checkout seen~4 $ git show -s --pretty=%s ;# double check - Merge branch 'ai/topic' to pu + Merge branch 'ai/topic' to seen $ edit $ git commit -m 'merge-fix/ai/topic' -a @@ -424,9 +450,9 @@ result: Then double check the result by asking Meta/Reintegrate to redo the merge: - $ git checkout pu~5 ;# the parent of the problem merge + $ git checkout seen~5 ;# the parent of the problem merge $ echo ai/topic | Meta/Reintegrate - $ git diff pu~4 + $ git diff seen~4 This time, because you prepared refs/merge-fix/ai/topic, the resulting merge should have been tweaked to include the fix for the @@ -438,7 +464,7 @@ branch needs this merge-fix is because another branch merged earlier to the integration branch changed the underlying assumption ai/topic branch made (e.g. ai/topic branch added a site to refer to a variable, while the other branch renamed that variable and adjusted -existing use sites), and if you changed redo-jch (or redo-pu) script +existing use sites), and if you changed redo-jch (or redo-seen) script to merge ai/topic branch before the other branch, then the above merge-fix should not be applied while merging ai/topic, but should instead be applied while merging the other branch. You would need diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.txt index 02cb5f758d..f2e10a7ec8 100644 --- a/Documentation/howto/rebase-from-internal-branch.txt +++ b/Documentation/howto/rebase-from-internal-branch.txt @@ -4,7 +4,7 @@ Cc: Petr Baudis <pasky@suse.cz>, Linus Torvalds <torvalds@osdl.org> Subject: Re: sending changesets from the middle of a git tree Date: Sun, 14 Aug 2005 18:37:39 -0700 Abstract: In this article, JC talks about how he rebases the - public "pu" branch using the core Git tools when he updates + public "seen" branch using the core Git tools when he updates the "master" branch, and how "rebase" works. Also discussed is how this applies to individual developers who sends patches upstream. @@ -20,8 +20,8 @@ Petr Baudis <pasky@suse.cz> writes: > where Junio C Hamano <junkio@cox.net> told me that... >> Linus Torvalds <torvalds@osdl.org> writes: >> ->> > Junio, maybe you want to talk about how you move patches from your "pu" ->> > branch to the real branches. +>> > Junio, maybe you want to talk about how you move patches from your +>> > "seen" branch to the real branches. >> > Actually, wouldn't this be also precisely for what StGIT is intended to? -------------------------------------- @@ -33,12 +33,12 @@ the kind of task StGIT is designed to do. I just have done a simpler one, this time using only the core Git tools. -I had a handful of commits that were ahead of master in pu, and I +I had a handful of commits that were ahead of master in 'seen', and I wanted to add some documentation bypassing my usual habit of -placing new things in pu first. At the beginning, the commit +placing new things in 'seen' first. At the beginning, the commit ancestry graph looked like this: - *"pu" head + *"seen" head master --> #1 --> #2 --> #3 So I started from master, made a bunch of edits, and committed: @@ -50,7 +50,7 @@ So I started from master, made a bunch of edits, and committed: After the commit, the ancestry graph would look like this: - *"pu" head + *"seen" head master^ --> #1 --> #2 --> #3 \ \---> master @@ -58,31 +58,31 @@ After the commit, the ancestry graph would look like this: The old master is now master^ (the first parent of the master). The new master commit holds my documentation updates. -Now I have to deal with "pu" branch. +Now I have to deal with "seen" branch. This is the kind of situation I used to have all the time when Linus was the maintainer and I was a contributor, when you look -at "master" branch being the "maintainer" branch, and "pu" +at "master" branch being the "maintainer" branch, and "seen" branch being the "contributor" branch. Your work started at the tip of the "maintainer" branch some time ago, you made a lot of progress in the meantime, and now the maintainer branch has some other commits you do not have yet. And "git rebase" was written with the explicit purpose of helping to maintain branches like -"pu". You _could_ merge master to pu and keep going, but if you +"seen". You _could_ merge master to 'seen' and keep going, but if you eventually want to cherrypick and merge some but not necessarily all changes back to the master branch, it often makes later operations for _you_ easier if you rebase (i.e. carry forward -your changes) "pu" rather than merge. So I ran "git rebase": +your changes) "seen" rather than merge. So I ran "git rebase": - $ git checkout pu - $ git rebase master pu + $ git checkout seen + $ git rebase master seen What this does is to pick all the commits since the current -branch (note that I now am on "pu" branch) forked from the +branch (note that I now am on "seen" branch) forked from the master branch, and forward port these changes. master^ --> #1 --> #2 --> #3 - \ *"pu" head + \ *"seen" head \---> master --> #1' --> #2' --> #3' The diff between master^ and #1 is applied to master and @@ -92,7 +92,7 @@ commits are made similarly out of #2 and #3 commits. Old #3 is not recorded in any of the .git/refs/heads/ file anymore, so after doing this you will have dangling commit if -you ran fsck-cache, which is normal. After testing "pu", you +you ran fsck-cache, which is normal. After testing "seen", you can run "git prune" to get rid of those original three commits. While I am talking about "git rebase", I should talk about how diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.txt index 149508e13b..a3e5595a56 100644 --- a/Documentation/howto/revert-branch-rebase.txt +++ b/Documentation/howto/revert-branch-rebase.txt @@ -15,7 +15,7 @@ One of the changes I pulled into the 'master' branch turns out to break building Git with GCC 2.95. While they were well-intentioned portability fixes, keeping things working with gcc-2.95 was also important. Here is what I did to revert the change in the 'master' -branch and to adjust the 'pu' branch, using core Git tools and +branch and to adjust the 'seen' branch, using core Git tools and barebone Porcelain. First, prepare a throw-away branch in case I screw things up. @@ -104,11 +104,11 @@ $ git diff master..revert-c99 says nothing. -Then we rebase the 'pu' branch as usual. +Then we rebase the 'seen' branch as usual. ------------------------------------------------ -$ git checkout pu -$ git tag pu-anchor pu +$ git checkout seen +$ git tag seen-anchor seen $ git rebase master * Applying: Redo "revert" using three-way merge machinery. First trying simple merge strategy to cherry-pick. @@ -127,11 +127,11 @@ First trying simple merge strategy to cherry-pick. First trying simple merge strategy to cherry-pick. ------------------------------------------------ -The temporary tag 'pu-anchor' is me just being careful, in case 'git +The temporary tag 'seen-anchor' is me just being careful, in case 'git rebase' screws up. After this, I can do these for sanity check: ------------------------------------------------ -$ git diff pu-anchor..pu ;# make sure we got the master fix. +$ git diff seen-anchor..seen ;# make sure we got the master fix. $ make CC=gcc-2.95 clean test ;# make sure it fixed the breakage. $ make clean test ;# make sure it did not cause other breakage. ------------------------------------------------ @@ -140,7 +140,7 @@ Everything is in the good order. I do not need the temporary branch or tag anymore, so remove them: ------------------------------------------------ -$ rm -f .git/refs/tags/pu-anchor +$ rm -f .git/refs/tags/seen-anchor $ git branch -d revert-c99 ------------------------------------------------ @@ -168,18 +168,18 @@ Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f And the final repository status looks like this: ------------------------------------------------ -$ git show-branch --more=1 master pu rc +$ git show-branch --more=1 master seen rc ! [master] Revert "Replace zero-length array decls with []." - ! [pu] git-repack: Add option to repack all objects. + ! [seen] git-repack: Add option to repack all objects. * [rc] Merge refs/heads/master from . --- - + [pu] git-repack: Add option to repack all objects. - + [pu~1] More documentation updates. - + [pu~2] Show commits in topo order and name all commits. - + [pu~3] mailinfo and applymbox updates - + [pu~4] Document "git cherry-pick" and "git revert" - + [pu~5] Remove git-apply-patch-script. - + [pu~6] Redo "revert" using three-way merge machinery. + + [seen] git-repack: Add option to repack all objects. + + [seen~1] More documentation updates. + + [seen~2] Show commits in topo order and name all commits. + + [seen~3] mailinfo and applymbox updates + + [seen~4] Document "git cherry-pick" and "git revert" + + [seen~5] Remove git-apply-patch-script. + + [seen~6] Redo "revert" using three-way merge machinery. - [rc] Merge refs/heads/master from . ++* [master] Revert "Replace zero-length array decls with []." - [rc~1] Merge refs/heads/master from . diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.txt index bd1027433b..81be0d6115 100644 --- a/Documentation/howto/separating-topic-branches.txt +++ b/Documentation/howto/separating-topic-branches.txt @@ -81,7 +81,7 @@ After I am done, I'd try a pretend-merge between "topicA" and o---o---o---o---o---o The last diff better not to show anything other than cleanups -for crufts. Then I can finally clean things up: +for cruft. Then I can finally clean things up: $ git branch -D topic $ git reset --hard HEAD^ ;# nuke pretend merge diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt index 89821ec74f..151ee84ceb 100644 --- a/Documentation/howto/update-hook-example.txt +++ b/Documentation/howto/update-hook-example.txt @@ -179,7 +179,7 @@ allowed-groups, to describe which heads can be pushed into by whom. The format of each file would look like this: refs/heads/master junio - +refs/heads/pu junio + +refs/heads/seen junio refs/heads/cogito$ pasky refs/heads/bw/.* linus refs/heads/tmp/.* .* @@ -187,6 +187,6 @@ whom. The format of each file would look like this: With this, Linus can push or create "bw/penguin" or "bw/zebra" or "bw/panda" branches, Pasky can do only "cogito", and JC can -do master and pu branches and make versioned tags. And anybody -can do tmp/blah branches. The '+' sign at the pu record means +do master and "seen" branches and make versioned tags. And anybody +can do tmp/blah branches. The '+' sign at the "seen" record means that JC can make non-fast-forward pushes on it. diff --git a/Documentation/i18n.txt b/Documentation/i18n.txt index 7e36e5b55b..6c6baeeeb7 100644 --- a/Documentation/i18n.txt +++ b/Documentation/i18n.txt @@ -38,7 +38,7 @@ mind. a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to - have i18n.commitencoding in `.git/config` file, like this: + have `i18n.commitEncoding` in `.git/config` file, like this: + ------------ [i18n] diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.txt index 829676ff98..9b51e9fb66 100644 --- a/Documentation/line-range-format.txt +++ b/Documentation/line-range-format.txt @@ -1,30 +1,32 @@ -<start> and <end> can take one of these forms: +'<start>' and '<end>' can take one of these forms: - number + -If <start> or <end> is a number, it specifies an +If '<start>' or '<end>' is a number, it specifies an absolute line number (lines count from 1). + -- /regex/ +- `/regex/` + This form will use the first line matching the given -POSIX regex. If <start> is a regex, it will search from the end of +POSIX regex. If '<start>' is a regex, it will search from the end of the previous `-L` range, if any, otherwise from the start of file. -If <start> is ``^/regex/'', it will search from the start of file. -If <end> is a regex, it will search -starting at the line given by <start>. +If '<start>' is `^/regex/`, it will search from the start of file. +If '<end>' is a regex, it will search +starting at the line given by '<start>'. + - +offset or -offset + -This is only valid for <end> and will specify a number -of lines before or after the line given by <start>. +This is only valid for '<end>' and will specify a number +of lines before or after the line given by '<start>'. + -If ``:<funcname>'' is given in place of <start> and <end>, it is a +If `:<funcname>` is given in place of '<start>' and '<end>', it is a regular expression that denotes the range from the first funcname line -that matches <funcname>, up to the next funcname line. ``:<funcname>'' +that matches '<funcname>', up to the next funcname line. `:<funcname>` searches from the end of the previous `-L` range, if any, otherwise -from the start of file. ``^:<funcname>'' searches from the start of -file. +from the start of file. `^:<funcname>` searches from the start of +file. The function names are determined in the same way as `git diff` +works out patch hunk headers (see 'Defining a custom hunk-header' +in linkgit:gitattributes[5]). diff --git a/Documentation/line-range-options.txt b/Documentation/line-range-options.txt new file mode 100644 index 0000000000..8e295a62b8 --- /dev/null +++ b/Documentation/line-range-options.txt @@ -0,0 +1,15 @@ +-L<start>,<end>:<file>:: +-L:<funcname>:<file>:: + + Trace the evolution of the line range given by '<start>,<end>', + or by the function name regex '<funcname>', within the '<file>'. You may + not give any pathspec limiters. This is currently limited to + a walk starting from a single revision, i.e., you may only + give zero or one positive revision arguments, and + '<start>' and '<end>' (or '<funcname>') must exist in the starting revision. + You can specify this option more than once. Implies `--patch`. + Patch output can be suppressed using `--no-patch`, but other diff formats + (namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`, + `--name-only`, `--name-status`, `--check`) are not currently implemented. ++ +include::line-range-format.txt[] diff --git a/Documentation/lint-gitlink.perl b/Documentation/lint-gitlink.perl index 476cc30b83..b22a367844 100755 --- a/Documentation/lint-gitlink.perl +++ b/Documentation/lint-gitlink.perl @@ -1,71 +1,67 @@ #!/usr/bin/perl -use File::Find; -use Getopt::Long; +use strict; +use warnings; -my $basedir = "."; -GetOptions("basedir=s" => \$basedir) - or die("Cannot parse command line arguments\n"); +# Parse arguments, a simple state machine for input like: +# +# howto/*.txt config/*.txt --section=1 git.txt git-add.txt [...] --to-lint git-add.txt a-file.txt [...] +my %TXT; +my %SECTION; +my $section; +my $lint_these = 0; +for my $arg (@ARGV) { + if (my ($sec) = $arg =~ /^--section=(\d+)$/s) { + $section = $sec; + next; + } -my $found_errors = 0; + my ($name) = $arg =~ /^(.*?)\.txt$/s; + unless (defined $section) { + $TXT{$name} = $arg; + next; + } -sub report { - my ($where, $what, $error) = @_; - print "$where: $error: $what\n"; - $found_errors = 1; + $SECTION{$name} = $section; } -sub grab_section { - my ($page) = @_; - open my $fh, "<", "$basedir/$page.txt"; - my $firstline = <$fh>; - chomp $firstline; - close $fh; - my ($section) = ($firstline =~ /.*\((\d)\)$/); - return $section; +my $exit_code = 0; +sub report { + my ($pos, $line, $target, $msg) = @_; + substr($line, $pos) = "' <-- HERE"; + $line =~ s/^\s+//; + print "$ARGV:$.: error: $target: $msg, shown with 'HERE' below:\n"; + print "$ARGV:$.:\t'$line\n"; + $exit_code = 1; } -sub lint { - my ($file) = @_; - open my $fh, "<", $file - or return; - while (<$fh>) { - my $where = "$file:$."; - while (s/linkgit:((.*?)\[(\d)\])//) { - my ($target, $page, $section) = ($1, $2, $3); +@ARGV = sort values %TXT; +die "BUG: Nothing to process!" unless @ARGV; +while (<>) { + my $line = $_; + while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) { + my $pos = pos $line; + my ($target, $page, $section) = ($1, $2, $3); - # De-AsciiDoc - $page =~ s/{litdd}/--/g; + # De-AsciiDoc + $page =~ s/{litdd}/--/g; - if ($page !~ /^git/) { - report($where, $target, "nongit link"); - next; - } - if (! -f "$basedir/$page.txt") { - report($where, $target, "no such source"); - next; - } - $real_section = grab_section($page); - if ($real_section != $section) { - report($where, $target, - "wrong section (should be $real_section)"); - next; - } + if (!exists $TXT{$page}) { + report($pos, $line, $target, "link outside of our own docs"); + next; + } + if (!exists $SECTION{$page}) { + report($pos, $line, $target, "link outside of our sectioned docs"); + next; + } + my $real_section = $SECTION{$page}; + if ($section != $SECTION{$page}) { + report($pos, $line, $target, "wrong section (should be $real_section)"); + next; } } - close $fh; -} - -sub lint_it { - lint($File::Find::name) if -f && /\.txt$/; -} - -if (!@ARGV) { - find({ wanted => \&lint_it, no_chdir => 1 }, $basedir); -} else { - for (@ARGV) { - lint($_); - } + # this resets our $. for each file + close ARGV if eof; } -exit $found_errors; +exit $exit_code; diff --git a/Documentation/lint-man-end-blurb.perl b/Documentation/lint-man-end-blurb.perl new file mode 100755 index 0000000000..d69312e5db --- /dev/null +++ b/Documentation/lint-man-end-blurb.perl @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($target, $msg) = @_; + print "error: $target: $msg\n"; + $exit_code = 1; +} + +local $/; +while (my $slurp = <>) { + report($ARGV, "has no 'Part of the linkgit:git[1] suite' end blurb") + unless $slurp =~ m[ + ^GIT\n + ---\n + \QPart of the linkgit:git[1] suite\E \n + \z + ]mx; +} + +exit $exit_code; diff --git a/Documentation/lint-man-section-order.perl b/Documentation/lint-man-section-order.perl new file mode 100755 index 0000000000..b05f9156dd --- /dev/null +++ b/Documentation/lint-man-section-order.perl @@ -0,0 +1,105 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my %SECTIONS; +{ + my $order = 0; + %SECTIONS = ( + 'NAME' => { + required => 1, + order => $order++, + }, + 'SYNOPSIS' => { + required => 1, + order => $order++, + }, + 'DESCRIPTION' => { + required => 1, + order => $order++, + }, + 'OPTIONS' => { + order => $order++, + required => 0, + }, + 'CONFIGURATION' => { + order => $order++, + }, + 'BUGS' => { + order => $order++, + }, + 'SEE ALSO' => { + order => $order++, + }, + 'GIT' => { + required => 1, + order => $order++, + }, + ); +} +my $SECTION_RX = do { + my ($names) = join "|", keys %SECTIONS; + qr/^($names)$/s; +}; + +my $exit_code = 0; +sub report { + my ($msg) = @_; + print "$ARGV:$.: $msg\n"; + $exit_code = 1; +} + +my $last_was_section; +my @actual_order; +while (my $line = <>) { + chomp $line; + if ($line =~ $SECTION_RX) { + push @actual_order => $line; + $last_was_section = 1; + # Have no "last" section yet, processing NAME + next if @actual_order == 1; + + my @expected_order = sort { + $SECTIONS{$a}->{order} <=> $SECTIONS{$b}->{order} + } @actual_order; + + my $expected_last = $expected_order[-2]; + my $actual_last = $actual_order[-2]; + if ($actual_last ne $expected_last) { + report("section '$line' incorrectly ordered, comes after '$actual_last'"); + } + next; + } + if ($last_was_section) { + my $last_section = $actual_order[-1]; + if (length $last_section ne length $line) { + report("dashes under '$last_section' should match its length!"); + } + if ($line !~ /^-+$/) { + report("dashes under '$last_section' should be '-' dashes!"); + } + $last_was_section = 0; + } + + if (eof) { + # We have both a hash and an array to consider, for + # convenience + my %actual_sections; + @actual_sections{@actual_order} = (); + + for my $section (sort keys %SECTIONS) { + next if !$SECTIONS{$section}->{required} or exists $actual_sections{$section}; + report("has no required '$section' section!"); + } + + # Reset per-file state + { + @actual_order = (); + # this resets our $. for each file + close ARGV; + } + } +} + +exit $exit_code; diff --git a/Documentation/mailmap.txt b/Documentation/mailmap.txt deleted file mode 100644 index 4a8c276529..0000000000 --- a/Documentation/mailmap.txt +++ /dev/null @@ -1,75 +0,0 @@ -If the file `.mailmap` exists at the toplevel of the repository, or at -the location pointed to by the mailmap.file or mailmap.blob -configuration options, it -is used to map author and committer names and email addresses to -canonical real names and email addresses. - -In the simple form, each line in the file consists of the canonical -real name of an author, whitespace, and an email address used in the -commit (enclosed by '<' and '>') to map to the name. For example: --- - Proper Name <commit@email.xx> --- - -The more complex forms are: --- - <proper@email.xx> <commit@email.xx> --- -which allows mailmap to replace only the email part of a commit, and: --- - Proper Name <proper@email.xx> <commit@email.xx> --- -which allows mailmap to replace both the name and the email of a -commit matching the specified commit email address, and: --- - Proper Name <proper@email.xx> Commit Name <commit@email.xx> --- -which allows mailmap to replace both the name and the email of a -commit matching both the specified commit name and email address. - -Example 1: Your history contains commits by two authors, Jane -and Joe, whose names appear in the repository under several forms: - ------------- -Joe Developer <joe@example.com> -Joe R. Developer <joe@example.com> -Jane Doe <jane@example.com> -Jane Doe <jane@laptop.(none)> -Jane D. <jane@desktop.(none)> ------------- - -Now suppose that Joe wants his middle name initial used, and Jane -prefers her family name fully spelled out. A proper `.mailmap` file -would look like: - ------------- -Jane Doe <jane@desktop.(none)> -Joe R. Developer <joe@example.com> ------------- - -Note how there is no need for an entry for `<jane@laptop.(none)>`, because the -real name of that author is already correct. - -Example 2: Your repository contains commits from the following -authors: - ------------- -nick1 <bugs@company.xx> -nick2 <bugs@company.xx> -nick2 <nick2@company.xx> -santa <me@company.xx> -claus <me@company.xx> -CTO <cto@coompany.xx> ------------- - -Then you might want a `.mailmap` file that looks like: ------------- -<cto@company.xx> <cto@coompany.xx> -Some Dude <some@dude.xx> nick1 <bugs@company.xx> -Other Author <other@author.xx> nick2 <bugs@company.xx> -Other Author <other@author.xx> <nick2@company.xx> -Santa Claus <santa.claus@northpole.xx> <me@company.xx> ------------- - -Use hash '#' for comments that are either on their own line, or after -the email address. diff --git a/Documentation/manpage-1.72.xsl b/Documentation/manpage-1.72.xsl deleted file mode 100644 index b4d315cb8c..0000000000 --- a/Documentation/manpage-1.72.xsl +++ /dev/null @@ -1,14 +0,0 @@ -<!-- manpage-1.72.xsl: - special settings for manpages rendered from asciidoc+docbook - handles peculiarities in docbook-xsl 1.72.0 --> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - version="1.0"> - -<xsl:import href="manpage-base.xsl"/> - -<!-- these are the special values for the roff control characters - needed for docbook-xsl 1.72.0 --> -<xsl:param name="git.docbook.backslash">▓</xsl:param> -<xsl:param name="git.docbook.dot" >⌂</xsl:param> - -</xsl:stylesheet> diff --git a/Documentation/manpage-base.xsl b/Documentation/manpage-base.xsl deleted file mode 100644 index a264fa6160..0000000000 --- a/Documentation/manpage-base.xsl +++ /dev/null @@ -1,35 +0,0 @@ -<!-- manpage-base.xsl: - special formatting for manpages rendered from asciidoc+docbook --> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - version="1.0"> - -<!-- these params silence some output from xmlto --> -<xsl:param name="man.output.quietly" select="1"/> -<xsl:param name="refentry.meta.get.quietly" select="1"/> - -<!-- convert asciidoc callouts to man page format; - git.docbook.backslash and git.docbook.dot params - must be supplied by another XSL file or other means --> -<xsl:template match="co"> - <xsl:value-of select="concat( - $git.docbook.backslash,'fB(', - substring-after(@id,'-'),')', - $git.docbook.backslash,'fR')"/> -</xsl:template> -<xsl:template match="calloutlist"> - <xsl:value-of select="$git.docbook.dot"/> - <xsl:text>sp </xsl:text> - <xsl:apply-templates/> - <xsl:text> </xsl:text> -</xsl:template> -<xsl:template match="callout"> - <xsl:value-of select="concat( - $git.docbook.backslash,'fB', - substring-after(@arearefs,'-'), - '. ',$git.docbook.backslash,'fR')"/> - <xsl:apply-templates/> - <xsl:value-of select="$git.docbook.dot"/> - <xsl:text>br </xsl:text> -</xsl:template> - -</xsl:stylesheet> diff --git a/Documentation/manpage-bold-literal.xsl b/Documentation/manpage-bold-literal.xsl index 608eb5df62..e13db85693 100644 --- a/Documentation/manpage-bold-literal.xsl +++ b/Documentation/manpage-bold-literal.xsl @@ -1,17 +1,16 @@ <!-- manpage-bold-literal.xsl: special formatting for manpages rendered from asciidoc+docbook --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:d="http://docbook.org/ns/docbook" version="1.0"> <!-- render literal text as bold (instead of plain or monospace); this makes literal text easier to distinguish in manpages viewed on a tty --> -<xsl:template match="literal"> - <xsl:value-of select="$git.docbook.backslash"/> - <xsl:text>fB</xsl:text> +<xsl:template match="literal|d:literal"> + <xsl:text>\fB</xsl:text> <xsl:apply-templates/> - <xsl:value-of select="$git.docbook.backslash"/> - <xsl:text>fR</xsl:text> + <xsl:text>\fR</xsl:text> </xsl:template> </xsl:stylesheet> diff --git a/Documentation/manpage-normal.xsl b/Documentation/manpage-normal.xsl index a48f5b11f3..a9c7ec69f4 100644 --- a/Documentation/manpage-normal.xsl +++ b/Documentation/manpage-normal.xsl @@ -1,13 +1,26 @@ <!-- manpage-normal.xsl: - special settings for manpages rendered from asciidoc+docbook - handles anything we want to keep away from docbook-xsl 1.72.0 --> + special settings for manpages rendered from asciidoc+docbook --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> -<xsl:import href="manpage-base.xsl"/> -<!-- these are the normal values for the roff control characters --> -<xsl:param name="git.docbook.backslash">\</xsl:param> -<xsl:param name="git.docbook.dot" >.</xsl:param> +<!-- these params silence some output from xmlto --> +<xsl:param name="man.output.quietly" select="1"/> +<xsl:param name="refentry.meta.get.quietly" select="1"/> + +<!-- convert asciidoc callouts to man page format --> +<xsl:template match="co"> + <xsl:value-of select="concat('\fB(',substring-after(@id,'-'),')\fR')"/> +</xsl:template> +<xsl:template match="calloutlist"> + <xsl:text>.sp </xsl:text> + <xsl:apply-templates/> + <xsl:text> </xsl:text> +</xsl:template> +<xsl:template match="callout"> + <xsl:value-of select="concat('\fB',substring-after(@arearefs,'-'),'. \fR')"/> + <xsl:apply-templates/> + <xsl:text>.br </xsl:text> +</xsl:template> </xsl:stylesheet> diff --git a/Documentation/manpage-suppress-sp.xsl b/Documentation/manpage-suppress-sp.xsl deleted file mode 100644 index a63c7632a8..0000000000 --- a/Documentation/manpage-suppress-sp.xsl +++ /dev/null @@ -1,21 +0,0 @@ -<!-- manpage-suppress-sp.xsl: - special settings for manpages rendered from asciidoc+docbook - handles erroneous, inline .sp in manpage output of some - versions of docbook-xsl --> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - version="1.0"> - -<!-- attempt to work around spurious .sp at the tail of the line - that some versions of docbook stylesheets seem to add --> -<xsl:template match="simpara"> - <xsl:variable name="content"> - <xsl:apply-templates/> - </xsl:variable> - <xsl:value-of select="normalize-space($content)"/> - <xsl:if test="not(ancestor::authorblurb) and - not(ancestor::personblurb)"> - <xsl:text> </xsl:text> - </xsl:if> -</xsl:template> - -</xsl:stylesheet> diff --git a/Documentation/manpage.xsl b/Documentation/manpage.xsl new file mode 100644 index 0000000000..ef64bab17a --- /dev/null +++ b/Documentation/manpage.xsl @@ -0,0 +1,3 @@ +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + <xsl:import href="http://docbook.sourceforge.net/release/xsl-ns/current/manpages/docbook.xsl" /> +</xsl:stylesheet> diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 79a00d2a4a..61ec157c2f 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -2,6 +2,9 @@ --no-commit:: Perform the merge and commit the result. This option can be used to override --no-commit. +ifdef::git-pull[] + Only useful when merging. +endif::git-pull[] + With --no-commit perform the merge and stop just before creating a merge commit, to give the user a chance to inspect and further @@ -34,52 +37,72 @@ set to `no` at the beginning of them. --cleanup=<mode>:: This option determines how the merge message will be cleaned up before - commiting. See linkgit:git-commit[1] for more details. In addition, if + committing. See linkgit:git-commit[1] for more details. In addition, if the '<mode>' is given a value of `scissors`, scissors will be appended to `MERGE_MSG` before being passed on to the commit machinery in the case of a merge conflict. +ifdef::git-merge[] --ff:: - When the merge resolves as a fast-forward, only update the branch - pointer, without creating a merge commit. This is the default - behavior. - --no-ff:: - Create a merge commit even when the merge resolves as a - fast-forward. This is the default behaviour when merging an - annotated (and possibly signed) tag that is not stored in - its natural place in 'refs/tags/' hierarchy. - --ff-only:: - Refuse to merge and exit with a non-zero status unless the - current `HEAD` is already up to date or the merge can be - resolved as a fast-forward. + Specifies how a merge is handled when the merged-in history is + already a descendant of the current history. `--ff` is the + default unless merging an annotated (and possibly signed) tag + that is not stored in its natural place in the `refs/tags/` + hierarchy, in which case `--no-ff` is assumed. +endif::git-merge[] +ifdef::git-pull[] +--ff-only:: + Only update to the new history if there is no divergent local + history. This is the default when no method for reconciling + divergent histories is provided (via the --rebase=* flags). + +--ff:: +--no-ff:: + When merging rather than rebasing, specifies how a merge is + handled when the merged-in history is already a descendant of + the current history. If merging is requested, `--ff` is the + default unless merging an annotated (and possibly signed) tag + that is not stored in its natural place in the `refs/tags/` + hierarchy, in which case `--no-ff` is assumed. +endif::git-pull[] ++ +With `--ff`, when possible resolve the merge as a fast-forward (only +update the branch pointer to match the merged branch; do not create a +merge commit). When not possible (when the merged-in history is not a +descendant of the current history), create a merge commit. ++ +With `--no-ff`, create a merge commit in all cases, even when the merge +could instead be resolved as a fast-forward. +ifdef::git-merge[] ++ +With `--ff-only`, resolve the merge as a fast-forward when possible. +When not possible, refuse to merge and exit with a non-zero status. +endif::git-merge[] -S[<keyid>]:: --gpg-sign[=<keyid>]:: +--no-gpg-sign:: GPG-sign the resulting merge commit. The `keyid` argument is optional and defaults to the committer identity; if specified, - it must be stuck to the option without a space. + it must be stuck to the option without a space. `--no-gpg-sign` + is useful to countermand both `commit.gpgSign` configuration variable, + and earlier `--gpg-sign`. --log[=<n>]:: --no-log:: In addition to branch names, populate the log message with one-line descriptions from at most <n> actual commits that are being merged. See also linkgit:git-fmt-merge-msg[1]. +ifdef::git-pull[] + Only useful when merging. +endif::git-pull[] + With --no-log do not list one-line descriptions from the actual commits being merged. ---signoff:: ---no-signoff:: - Add Signed-off-by line by the committer at the end of the commit - log message. The meaning of a signoff depends on the project, - but it typically certifies that committer has - the rights to submit this work under the same license and - agrees to a Developer Certificate of Origin - (see http://developercertificate.org/ for more information). -+ -With --no-signoff do not add a Signed-off-by line. +include::signoff-option.txt[] --stat:: -n:: @@ -104,14 +127,25 @@ With --no-squash perform the merge and commit the result. This option can be used to override --squash. + With --squash, --commit is not allowed, and will fail. +ifdef::git-pull[] ++ +Only useful when merging. +endif::git-pull[] + +--no-verify:: + This option bypasses the pre-merge and commit-msg hooks. + See also linkgit:githooks[5]. +ifdef::git-pull[] + Only useful when merging. +endif::git-pull[] -s <strategy>:: --strategy=<strategy>:: Use the given merge strategy; can be supplied more than once to specify them in the order they should be tried. If there is no `-s` option, a built-in list of strategies - is used instead ('git merge-recursive' when merging a single - head, 'git merge-octopus' otherwise). + is used instead (`ort` when merging a single head, + `octopus` otherwise). -X <option>:: --strategy-option=<option>:: @@ -125,6 +159,10 @@ With --squash, --commit is not allowed, and will fail. default trust model, this means the signing key has been signed by a trusted key. If the tip commit of the side branch is not signed with a valid key, the merge is aborted. +ifdef::git-pull[] ++ +Only useful when merging. +endif::git-pull[] --summary:: --no-summary:: @@ -149,6 +187,15 @@ ifndef::git-pull[] endif::git-pull[] +--autostash:: +--no-autostash:: + Automatically create a temporary stash entry before the operation + begins, record it in the special ref `MERGE_AUTOSTASH` + and apply it after the operation ends. This means + that you can run the operation on a dirty worktree. However, use + with care: the final stash application after a successful + merge might result in non-trivial conflicts. + --allow-unrelated-histories:: By default, `git merge` command refuses to merge histories that do not share a common ancestor. This option can be @@ -156,3 +203,7 @@ endif::git-pull[] projects that started their lives independently. As that is a very rare occasion, no configuration variable to enable this by default exists and will not be added. +ifdef::git-pull[] ++ +Only useful when merging. +endif::git-pull[] diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.txt index aa66cbe41e..5fc54ec060 100644 --- a/Documentation/merge-strategies.txt +++ b/Documentation/merge-strategies.txt @@ -6,33 +6,28 @@ backend 'merge strategies' to be chosen with `-s` option. Some strategies can also take their own options, which can be passed by giving `-X<option>` arguments to `git merge` and/or `git pull`. -resolve:: - This can only resolve two heads (i.e. the current branch - and another branch you pulled from) using a 3-way merge - algorithm. It tries to carefully detect criss-cross - merge ambiguities and is considered generally safe and - fast. - -recursive:: - This can only resolve two heads using a 3-way merge - algorithm. When there is more than one common - ancestor that can be used for 3-way merge, it creates a - merged tree of the common ancestors and uses that as - the reference tree for the 3-way merge. This has been - reported to result in fewer merge conflicts without - causing mismerges by tests done on actual merge commits - taken from Linux 2.6 kernel development history. - Additionally this can detect and handle merges involving - renames, but currently cannot make use of detected - copies. This is the default merge strategy when pulling - or merging one branch. +ort:: + This is the default merge strategy when pulling or merging one + branch. This strategy can only resolve two heads using a + 3-way merge algorithm. When there is more than one common + ancestor that can be used for 3-way merge, it creates a merged + tree of the common ancestors and uses that as the reference + tree for the 3-way merge. This has been reported to result in + fewer merge conflicts without causing mismerges by tests done + on actual merge commits taken from Linux 2.6 kernel + development history. Additionally this strategy can detect + and handle merges involving renames. It does not make use of + detected copies. The name for this algorithm is an acronym + ("Ostensibly Recursive's Twin") and came from the fact that it + was written as a replacement for the previous default + algorithm, `recursive`. + -The 'recursive' strategy can take the following options: +The 'ort' strategy can take the following options: ours;; This option forces conflicting hunks to be auto-resolved cleanly by favoring 'our' version. Changes from the other tree that do not - conflict with our side are reflected to the merge result. + conflict with our side are reflected in the merge result. For a binary file, the entire contents are taken from our side. + This should not be confused with the 'ours' merge strategy, which does not @@ -43,19 +38,6 @@ theirs;; This is the opposite of 'ours'; note that, unlike 'ours', there is no 'theirs' merge strategy to confuse this merge option with. -patience;; - With this option, 'merge-recursive' spends a little extra time - to avoid mismerges that sometimes occur due to unimportant - matching lines (e.g., braces from distinct functions). Use - this when the branches to be merged have diverged wildly. - See also linkgit:git-diff[1] `--patience`. - -diff-algorithm=[patience|minimal|histogram|myers];; - Tells 'merge-recursive' to use a different diff algorithm, which - can help avoid mismerges that occur due to unimportant matching - lines (such as braces from distinct functions). See also - linkgit:git-diff[1] `--diff-algorithm`. - ignore-space-change;; ignore-all-space;; ignore-space-at-eol;; @@ -84,11 +66,6 @@ no-renormalize;; Disables the `renormalize` option. This overrides the `merge.renormalize` configuration variable. -no-renames;; - Turn off rename detection. This overrides the `merge.renames` - configuration variable. - See also linkgit:git-diff[1] `--no-renames`. - find-renames[=<n>];; Turn on rename detection, optionally setting the similarity threshold. This is the default. This overrides the @@ -105,6 +82,46 @@ subtree[=<path>];; is prefixed (or stripped from the beginning) to make the shape of two trees to match. +recursive:: + This can only resolve two heads using a 3-way merge + algorithm. When there is more than one common + ancestor that can be used for 3-way merge, it creates a + merged tree of the common ancestors and uses that as + the reference tree for the 3-way merge. This has been + reported to result in fewer merge conflicts without + causing mismerges by tests done on actual merge commits + taken from Linux 2.6 kernel development history. + Additionally this can detect and handle merges involving + renames. It does not make use of detected copies. This was + the default strategy for resolving two heads from Git v0.99.9k + until v2.33.0. ++ +The 'recursive' strategy takes the same options as 'ort'. However, +there are three additional options that 'ort' ignores (not documented +above) that are potentially useful with the 'recursive' strategy: + +patience;; + Deprecated synonym for `diff-algorithm=patience`. + +diff-algorithm=[patience|minimal|histogram|myers];; + Use a different diff algorithm while merging, which can help + avoid mismerges that occur due to unimportant matching lines + (such as braces from distinct functions). See also + linkgit:git-diff[1] `--diff-algorithm`. Note that `ort` + specifically uses `diff-algorithm=histogram`, while `recursive` + defaults to the `diff.algorithm` config setting. + +no-renames;; + Turn off rename detection. This overrides the `merge.renames` + configuration variable. + See also linkgit:git-diff[1] `--no-renames`. + +resolve:: + This can only resolve two heads (i.e. the current branch + and another branch you pulled from) using a 3-way merge + algorithm. It tries to carefully detect criss-cross + merge ambiguities. It does not handle renames. + octopus:: This resolves cases with more than two heads, but refuses to do a complex merge that needs manual resolution. It is @@ -121,13 +138,13 @@ ours:: the 'recursive' merge strategy. subtree:: - This is a modified recursive strategy. When merging trees A and + This is a modified `ort` strategy. When merging trees A and B, if B corresponds to a subtree of A, B is first adjusted to match the tree structure of A, instead of reading the trees at the same level. This adjustment is also done to the common ancestor tree. -With the strategies that use 3-way merge (including the default, 'recursive'), +With the strategies that use 3-way merge (including the default, 'ort'), if a change is made on both branches, but later reverted on one of the branches, that change will be present in the merged result; some people find this behavior confusing. It occurs because only the heads and the merge base diff --git a/Documentation/object-format-disclaimer.txt b/Documentation/object-format-disclaimer.txt new file mode 100644 index 0000000000..4cb106f0d1 --- /dev/null +++ b/Documentation/object-format-disclaimer.txt @@ -0,0 +1,6 @@ +THIS OPTION IS EXPERIMENTAL! SHA-256 support is experimental and still +in an early stage. A SHA-256 repository will in general not be able to +share work with "regular" SHA-1 repositories. It should be assumed +that, e.g., Git internal file formats in relation to SHA-256 +repositories may change in backwards-incompatible ways. Only use +`--object-format=sha256` for testing purposes. diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 079598307a..ef6bd420ae 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -4,7 +4,7 @@ PRETTY FORMATS If the commit is a merge, and if the pretty-format is not 'oneline', 'email' or 'raw', an additional line is inserted before the 'Author:' line. This line begins with -"Merge: " and the sha1s of ancestral commits are printed, +"Merge: " and the hashes of ancestral commits are printed, separated by spaces. Note that the listed commits may not necessarily be the list of the *direct* parent commits if you have limited your view of history: for example, if you are @@ -20,20 +20,20 @@ built-in formats: * 'oneline' - <sha1> <title line> + <hash> <title line> + This is designed to be as compact as possible. * 'short' - commit <sha1> + commit <hash> Author: <author> <title line> * 'medium' - commit <sha1> + commit <hash> Author: <author> Date: <author date> @@ -43,7 +43,7 @@ This is designed to be as compact as possible. * 'full' - commit <sha1> + commit <hash> Author: <author> Commit: <committer> @@ -53,7 +53,7 @@ This is designed to be as compact as possible. * 'fuller' - commit <sha1> + commit <hash> Author: <author> AuthorDate: <author date> Commit: <committer> @@ -63,19 +63,36 @@ This is designed to be as compact as possible. <full commit message> +* 'reference' + + <abbrev hash> (<title line>, <short author date>) ++ +This format is used to refer to another commit in a commit message and +is the same as `--pretty='format:%C(auto)%h (%s, %ad)'`. By default, +the date is formatted with `--date=short` unless another `--date` option +is explicitly specified. As with any `format:` with format +placeholders, its output is not affected by other options like +`--decorate` and `--walk-reflogs`. + * 'email' - From <sha1> <date> + From <hash> <date> From: <author> Date: <author date> Subject: [PATCH] <title line> <full commit message> +* 'mboxrd' ++ +Like 'email', but lines in the commit message starting with "From " +(preceded by zero or more ">") are quoted with ">" so they aren't +confused as starting a new commit. + * 'raw' + The 'raw' format shows the entire commit exactly as -stored in the commit object. Notably, the SHA-1s are +stored in the commit object. Notably, the hashes are displayed in full, regardless of whether --abbrev or --no-abbrev are used, and 'parents' information show the true parent commits, without taking grafts or history @@ -163,26 +180,51 @@ The placeholders are: '%ae':: author email '%aE':: author email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%al':: author email local-part (the part before the '@' sign) +'%aL':: author local-part (see '%al') respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) '%ad':: author date (format respects --date= option) '%aD':: author date, RFC2822 style '%ar':: author date, relative '%at':: author date, UNIX timestamp '%ai':: author date, ISO 8601-like format '%aI':: author date, strict ISO 8601 format +'%as':: author date, short format (`YYYY-MM-DD`) +'%ah':: author date, human style (like the `--date=human` option of + linkgit:git-rev-list[1]) '%cn':: committer name '%cN':: committer name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) '%ce':: committer email '%cE':: committer email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%cl':: committer email local-part (the part before the '@' sign) +'%cL':: committer local-part (see '%cl') respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) '%cd':: committer date (format respects --date= option) '%cD':: committer date, RFC2822 style '%cr':: committer date, relative '%ct':: committer date, UNIX timestamp '%ci':: committer date, ISO 8601-like format '%cI':: committer date, strict ISO 8601 format +'%cs':: committer date, short format (`YYYY-MM-DD`) +'%ch':: committer date, human style (like the `--date=human` option of + linkgit:git-rev-list[1]) '%d':: ref names, like the --decorate option of linkgit:git-log[1] '%D':: ref names without the " (", ")" wrapping. +'%(describe[:options])':: human-readable name, like + linkgit:git-describe[1]; empty string for + undescribable commits. The `describe` string + may be followed by a colon and zero or more + comma-separated options. Descriptions can be + inconsistent when tags are added or removed at + the same time. ++ +** 'match=<pattern>': Only consider tags matching the given + `glob(7)` pattern, excluding the "refs/tags/" prefix. +** 'exclude=<pattern>': Do not consider tags matching the given + `glob(7)` pattern, excluding the "refs/tags/" prefix. + '%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 @@ -207,8 +249,9 @@ endif::git-rev-list[] '%GF':: show the fingerprint of the key used to sign a signed commit '%GP':: show the fingerprint of the primary key whose subkey was used to sign a signed commit +'%GT':: show the trust level for the key used to sign a signed commit '%gD':: reflog selector, e.g., `refs/stash@{1}` or `refs/stash@{2 - minutes ago`}; the format follows the rules described for the + minutes ago}`; the format follows the rules described for the `-g` option. The portion before the `@` is the refname as given on the command line (so `git log -g refs/heads/master` would yield `refs/heads/master@{0}`). @@ -226,7 +269,15 @@ endif::git-rev-list[] interpreted by linkgit:git-interpret-trailers[1]. The `trailers` string may be followed by a colon - and zero or more comma-separated options: + and zero or more comma-separated options. + If any option is provided multiple times the + last occurrence wins. ++ +The boolean options accept an optional value `[=<BOOL>]`. The values +`true`, `false`, `on`, `off` etc. are all accepted. See the "boolean" +sub-section in "EXAMPLES" in linkgit:git-config[1]. If a boolean +option is given with no value, it's enabled. ++ ** 'key=<K>': only show trailers with specified key. Matching is done case-insensitively and trailing colon is optional. If option is given multiple times trailer lines matching any of the keys are @@ -235,27 +286,25 @@ endif::git-rev-list[] desired it can be disabled with `only=false`. E.g., `%(trailers:key=Reviewed-by)` shows trailer lines with key `Reviewed-by`. -** 'only[=val]': select whether non-trailer lines from the trailer - block should be included. The `only` keyword may optionally be - followed by an equal sign and one of `true`, `on`, `yes` to omit or - `false`, `off`, `no` to show the non-trailer lines. If option is - given without value it is enabled. If given multiple times the last - value is used. +** 'only[=<BOOL>]': select whether non-trailer lines from the trailer + block should be included. ** 'separator=<SEP>': specify a separator inserted between trailer lines. When this option is not given each trailer line is terminated with a line feed character. The string SEP may contain the literal formatting codes described above. To use comma as separator one must use `%x2C` as it would otherwise be parsed as - next option. If separator option is given multiple times only the - last one is used. E.g., `%(trailers:key=Ticket,separator=%x2C )` + next option. E.g., `%(trailers:key=Ticket,separator=%x2C )` shows all trailer lines whose key is "Ticket" separated by a comma and a space. -** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold` - option was given. In same way as to for `only` it can be followed - by an equal sign and explicit value. E.g., +** 'unfold[=<BOOL>]': make it behave as if interpret-trailer's `--unfold` + option was given. E.g., `%(trailers:only,unfold=true)` unfolds and shows all trailer lines. -** 'valueonly[=val]': skip over the key part of the trailer line and only - show the value part. Also this optionally allows explicit value. +** 'keyonly[=<BOOL>]': only show the key part of the trailer. +** 'valueonly[=<BOOL>]': only show the value part of the trailer. +** 'key_value_separator=<SEP>': specify a separator inserted between + trailer lines. When this option is not given each trailer key-value + pair is separated by ": ". Otherwise it shares the same semantics + as 'separator=<SEP>' above. NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.txt index e44fc8f738..27ddaf84a1 100644 --- a/Documentation/pretty-options.txt +++ b/Documentation/pretty-options.txt @@ -3,7 +3,7 @@ Pretty-print the contents of the commit logs in a given format, where '<format>' can be one of 'oneline', 'short', 'medium', - 'full', 'fuller', 'email', 'raw', 'format:<string>' + 'full', 'fuller', 'reference', 'email', 'raw', 'format:<string>' and 'tformat:<string>'. When '<format>' is none of the above, and has '%placeholder' in it, it acts as if '--pretty=tformat:<format>' were given. @@ -16,17 +16,17 @@ configuration (see linkgit:git-config[1]). --abbrev-commit:: Instead of showing the full 40-byte hexadecimal commit object - name, show only a partial prefix. Non default number of - digits can be specified with "--abbrev=<n>" (which also modifies - diff output, if it is displayed). + name, show a prefix that names the object uniquely. + "--abbrev=<n>" (which also modifies diff output, if it is displayed) + option can be used to specify the minimum length of the prefix. + This should make "--pretty=oneline" a whole lot more readable for people using 80-column terminals. --no-abbrev-commit:: Show the full 40-byte hexadecimal commit object name. This negates - `--abbrev-commit` and those options which imply it such as - "--oneline". It also overrides the `log.abbrevCommit` variable. + `--abbrev-commit`, either explicit or implied by other options such + as "--oneline". It also overrides the `log.abbrevCommit` variable. --oneline:: This is a shorthand for "--pretty=oneline --abbrev-commit" @@ -57,7 +57,7 @@ message by 4 spaces (i.e. 'medium', which is the default, 'full', and 'fuller'). ifndef::git-rev-list[] ---notes[=<treeish>]:: +--notes[=<ref>]:: Show the notes (see linkgit:git-notes[1]) that annotate the commit, when showing the commit log message. This is the default for `git log`, `git show` and `git whatchanged` commands when @@ -68,8 +68,8 @@ By default, the notes shown are from the notes refs listed in the `core.notesRef` and `notes.displayRef` variables (or corresponding environment overrides). See linkgit:git-config[1] for more details. + -With an optional '<treeish>' argument, use the treeish to find the notes -to display. The treeish can specify the full refname when it begins +With an optional '<ref>' argument, use the ref to find the notes +to display. The ref can specify the full refname when it begins with `refs/notes/`; when it begins with `notes/`, `refs/` and otherwise `refs/notes/` is prefixed to form a full name of the ref. + @@ -85,7 +85,7 @@ being displayed. Examples: "--notes=foo" will show only notes from "--notes --notes=foo --no-notes --notes=bar" will only show notes from "refs/notes/bar". ---show-notes[=<treeish>]:: +--show-notes[=<ref>]:: --[no-]standard-notes:: These options are deprecated. Use the above --notes/--no-notes options instead. diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index 7d3a60f5b9..95a7390b2c 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -19,7 +19,8 @@ ifndef::git-pull[] (see <<CRTB,CONFIGURED REMOTE-TRACKING BRANCHES>> below). endif::git-pull[] ifdef::git-pull[] - (see linkgit:git-fetch[1]). + (see the section "CONFIGURED REMOTE-TRACKING BRANCHES" + in linkgit:git-fetch[1]). endif::git-pull[] + The format of a <refspec> parameter is an optional plus @@ -29,6 +30,22 @@ The colon can be omitted when <dst> is empty. <src> is typically a ref, but it can also be a fully spelled hex object name. + +A <refspec> may contain a `*` in its <src> to indicate a simple pattern +match. Such a refspec functions like a glob that matches any ref with the +same prefix. A pattern <refspec> must have a `*` in both the <src> and +<dst>. It will map refs to the destination by replacing the `*` with the +contents matched from the source. ++ +If a refspec is prefixed by `^`, it will be interpreted as a negative +refspec. Rather than specifying which refs to fetch or which local refs to +update, such a refspec will instead specify refs to exclude. A ref will be +considered to match if it matches at least one positive refspec, and does +not match any negative refspec. Negative refspecs can be useful to restrict +the scope of a pattern refspec so that it will not include specific refs. +Negative refspecs can themselves be pattern refspecs. However, they may only +contain a <src> and do not specify a <dst>. Fully spelled out hex object +names are also not supported. ++ `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`; it requests fetching everything up to the given tag. + diff --git a/Documentation/ref-reachability-filters.txt b/Documentation/ref-reachability-filters.txt new file mode 100644 index 0000000000..9bae46d84c --- /dev/null +++ b/Documentation/ref-reachability-filters.txt @@ -0,0 +1,7 @@ +When combining multiple `--contains` and `--no-contains` filters, only +references that contain at least one of the `--contains` commits and +contain none of the `--no-contains` commits are shown. + +When combining multiple `--merged` and `--no-merged` filters, only +references that are reachable from at least one of the `--merged` +commits and from none of the `--no-merged` commits are shown. diff --git a/Documentation/rev-list-description.txt b/Documentation/rev-list-description.txt new file mode 100644 index 0000000000..a9efa7fa27 --- /dev/null +++ b/Documentation/rev-list-description.txt @@ -0,0 +1,61 @@ +List commits that are reachable by following the `parent` links from the +given commit(s), but exclude commits that are reachable from the one(s) +given with a '{caret}' in front of them. The output is given in reverse +chronological order by default. + +You can think of this as a set operation. Commits reachable from any of +the commits given on the command line form a set, and then commits reachable +from any of the ones given with '{caret}' in front are subtracted from that +set. The remaining commits are what comes out in the command's output. +Various other options and paths parameters can be used to further limit the +result. + +Thus, the following command: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list foo bar ^baz +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log foo bar ^baz +----------------------------------------------------------------------- +endif::git-log[] + +means "list all the commits which are reachable from 'foo' or 'bar', but +not from 'baz'". + +A special notation "'<commit1>'..'<commit2>'" can be used as a +short-hand for "^'<commit1>' '<commit2>'". For example, either of +the following may be used interchangeably: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list origin..HEAD +$ git rev-list HEAD ^origin +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log origin..HEAD +$ git log HEAD ^origin +----------------------------------------------------------------------- +endif::git-log[] + +Another special notation is "'<commit1>'...'<commit2>'" which is useful +for merges. The resulting set of commits is the symmetric difference +between the two operands. The following two commands are equivalent: + +ifdef::git-rev-list[] +----------------------------------------------------------------------- +$ git rev-list A B --not $(git merge-base --all A B) +$ git rev-list A...B +----------------------------------------------------------------------- +endif::git-rev-list[] +ifdef::git-log[] +----------------------------------------------------------------------- +$ git log A B --not $(git merge-base --all A B) +$ git log A...B +----------------------------------------------------------------------- +endif::git-log[] diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 71a1fcc093..24569b06d1 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -58,7 +58,7 @@ endif::git-rev-list[] `--all-match`). ifndef::git-rev-list[] + -When `--show-notes` is in effect, the message from the notes is +When `--notes` is in effect, the message from the notes is matched as if it were part of the log message. endif::git-rev-list[] @@ -128,8 +128,12 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit). because merges into a topic branch tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits - brought in to your history by such a merge. Cannot be - combined with --bisect. + brought in to your history by such a merge. +ifdef::git-log[] ++ +This option also changes default diff format for merge commits +to `first-parent`, see `--diff-merges=first-parent` for details. +endif::git-log[] --not:: Reverses the meaning of the '{caret}' prefix (or lack thereof) @@ -182,6 +186,14 @@ explicitly. Pretend as if all objects mentioned by reflogs are listed on the command line as `<commit>`. +--alternate-refs:: + Pretend as if all objects mentioned as ref tips of alternate + repositories were listed on the command line. An alternate + repository is any repository whose object directory is specified + in `objects/info/alternates`. The set of included objects may + be modified by `core.alternateRefsCommand`, etc. See + linkgit:git-config[1]. + --single-worktree:: By default, all working trees will be examined by the following options when there are more than one (see @@ -199,7 +211,7 @@ ifndef::git-rev-list[] Pretend as if the bad bisection ref `refs/bisect/bad` was listed and as if it was followed by `--not` and the good bisection refs `refs/bisect/good-*` on the command - line. Cannot be combined with --first-parent. + line. endif::git-rev-list[] --stdin:: @@ -215,6 +227,15 @@ ifdef::git-rev-list[] test the exit status to see if a range of objects is fully connected (or not). It is faster than redirecting stdout to `/dev/null` as the output does not have to be formatted. + +--disk-usage:: + Suppress normal output; instead, print the sum of the bytes used + for on-disk storage by the selected commits or objects. This is + equivalent to piping the output into `git cat-file + --batch-check='%(objectsize:disk)'`, except that it runs much + faster (especially with `--use-bitmap-index`). See the `CAVEATS` + section in linkgit:git-cat-file[1] for the limitations of what + "on-disk storage" means. endif::git-rev-list[] --cherry-mark:: @@ -261,7 +282,7 @@ list. exclude (that is, '{caret}commit', 'commit1..commit2', and 'commit1\...commit2' notations cannot be used). + -With `--pretty` format other than `oneline` (for obvious reasons), +With `--pretty` format other than `oneline` and `reference` (for obvious reasons), this causes the output to have two extra lines of information taken from the reflog. The reflog designator in the output may be shown as `ref@{Nth}` (where `Nth` is the reverse-chronological index in the @@ -285,6 +306,8 @@ Under `--pretty=oneline`, the commit message is prefixed with this information on the same line. This option cannot be combined with `--reverse`. See also linkgit:git-reflog[1]. ++ +Under `--pretty=reference`, this information will not be shown at all. --merge:: After a failed merge, show refs that touch files having a @@ -332,6 +355,12 @@ Default mode:: branches if the end result is the same (i.e. merging branches with the same content) +--show-pulls:: + Include all commits from the default mode, but also any merge + commits that are not TREESAME to the first parent but are + TREESAME to a later parent. This mode is helpful for showing + the merge commits that "first introduced" a change to a branch. + --full-history:: Same as the default mode, but does not prune some history. @@ -524,7 +553,7 @@ Note the major differences in `N`, `P`, and `Q` over `--full-history`: parent and is TREESAME. -- -Finally, there is a fifth simplification mode available: +There is another simplification mode available: --ancestry-path:: Limit the displayed commits to those directly on the ancestry @@ -563,6 +592,135 @@ option does. Applied to the 'D..M' range, it results in: L--M ----------------------------------------------------------------------- +Before discussing another option, `--show-pulls`, we need to +create a new example history. + +A common problem users face when looking at simplified history is that a +commit they know changed a file somehow does not appear in the file's +simplified history. Let's demonstrate a new example and show how options +such as `--full-history` and `--simplify-merges` works in that case: + +----------------------------------------------------------------------- + .-A---M-----C--N---O---P + / / \ \ \/ / / + I B \ R-'`-Z' / + \ / \/ / + \ / /\ / + `---X--' `---Y--' +----------------------------------------------------------------------- + +For this example, suppose `I` created `file.txt` which was modified by +`A`, `B`, and `X` in different ways. The single-parent commits `C`, `Z`, +and `Y` do not change `file.txt`. The merge commit `M` was created by +resolving the merge conflict to include both changes from `A` and `B` +and hence is not TREESAME to either. The merge commit `R`, however, was +created by ignoring the contents of `file.txt` at `M` and taking only +the contents of `file.txt` at `X`. Hence, `R` is TREESAME to `X` but not +`M`. Finally, the natural merge resolution to create `N` is to take the +contents of `file.txt` at `R`, so `N` is TREESAME to `R` but not `C`. +The merge commits `O` and `P` are TREESAME to their first parents, but +not to their second parents, `Z` and `Y` respectively. + +When using the default mode, `N` and `R` both have a TREESAME parent, so +those edges are walked and the others are ignored. The resulting history +graph is: + +----------------------------------------------------------------------- + I---X +----------------------------------------------------------------------- + +When using `--full-history`, Git walks every edge. This will discover +the commits `A` and `B` and the merge `M`, but also will reveal the +merge commits `O` and `P`. With parent rewriting, the resulting graph is: + +----------------------------------------------------------------------- + .-A---M--------N---O---P + / / \ \ \/ / / + I B \ R-'`--' / + \ / \/ / + \ / /\ / + `---X--' `------' +----------------------------------------------------------------------- + +Here, the merge commits `O` and `P` contribute extra noise, as they did +not actually contribute a change to `file.txt`. They only merged a topic +that was based on an older version of `file.txt`. This is a common +issue in repositories using a workflow where many contributors work in +parallel and merge their topic branches along a single trunk: manu +unrelated merges appear in the `--full-history` results. + +When using the `--simplify-merges` option, the commits `O` and `P` +disappear from the results. This is because the rewritten second parents +of `O` and `P` are reachable from their first parents. Those edges are +removed and then the commits look like single-parent commits that are +TREESAME to their parent. This also happens to the commit `N`, resulting +in a history view as follows: + +----------------------------------------------------------------------- + .-A---M--. + / / \ + I B R + \ / / + \ / / + `---X--' +----------------------------------------------------------------------- + +In this view, we see all of the important single-parent changes from +`A`, `B`, and `X`. We also see the carefully-resolved merge `M` and the +not-so-carefully-resolved merge `R`. This is usually enough information +to determine why the commits `A` and `B` "disappeared" from history in +the default view. However, there are a few issues with this approach. + +The first issue is performance. Unlike any previous option, the +`--simplify-merges` option requires walking the entire commit history +before returning a single result. This can make the option difficult to +use for very large repositories. + +The second issue is one of auditing. When many contributors are working +on the same repository, it is important which merge commits introduced +a change into an important branch. The problematic merge `R` above is +not likely to be the merge commit that was used to merge into an +important branch. Instead, the merge `N` was used to merge `R` and `X` +into the important branch. This commit may have information about why +the change `X` came to override the changes from `A` and `B` in its +commit message. + +--show-pulls:: + In addition to the commits shown in the default history, show + each merge commit that is not TREESAME to its first parent but + is TREESAME to a later parent. ++ +When a merge commit is included by `--show-pulls`, the merge is +treated as if it "pulled" the change from another branch. When using +`--show-pulls` on this example (and no other options) the resulting +graph is: ++ +----------------------------------------------------------------------- + I---X---R---N +----------------------------------------------------------------------- ++ +Here, the merge commits `R` and `N` are included because they pulled +the commits `X` and `R` into the base branch, respectively. These +merges are the reason the commits `A` and `B` do not appear in the +default history. ++ +When `--show-pulls` is paired with `--simplify-merges`, the +graph includes all of the necessary information: ++ +----------------------------------------------------------------------- + .-A---M--. N + / / \ / + I B R + \ / / + \ / / + `---X--' +----------------------------------------------------------------------- ++ +Notice that since `M` is reachable from `R`, the edge from `N` to `M` +was simplified away. However, `N` still appears in the history as an +important commit because it "pulled" the change `R` into the main +branch. + The `--simplify-by-decoration` option allows you to view only the big picture of the topology of the history, by omitting commits that are not referenced by tags. Commits are marked as !TREESAME @@ -571,6 +729,7 @@ above) if (1) they are referenced by tags, or (2) they change the contents of the paths given on the command line. All other commits are marked as TREESAME (subject to be simplified away). +ifndef::git-shortlog[] ifdef::git-rev-list[] Bisection Helpers ~~~~~~~~~~~~~~~~~ @@ -597,7 +756,7 @@ outputs 'midpoint', the output of the two commands would be of roughly the same length. Finding the change which introduces a regression is thus reduced to a binary search: repeatedly generate and test new 'midpoint's until the commit chain is of length -one. Cannot be combined with --first-parent. +one. --bisect-vars:: This calculates the same as `--bisect`, except that refs in @@ -626,8 +785,9 @@ This option can be used along with `--bisect-vars`, in this case, after all the sorted commit objects, there will be the same text as if `--bisect-vars` had been used alone. endif::git-rev-list[] +endif::git-shortlog[] - +ifndef::git-shortlog[] Commit Ordering ~~~~~~~~~~~~~~~ @@ -669,7 +829,9 @@ together. Output the commits chosen to be shown (see Commit Limiting section above) in reverse order. Cannot be combined with `--walk-reflogs`. +endif::git-shortlog[] +ifndef::git-shortlog[] Object Traversal ~~~~~~~~~~~~~~~~ @@ -708,6 +870,16 @@ ifdef::git-rev-list[] Only useful with `--objects`; print the object IDs that are not in packs. +--object-names:: + Only useful with `--objects`; print the names of the object IDs + that are found. This is the default behavior. + +--no-object-names:: + Only useful with `--objects`; does not print the names of the object + IDs that are found. This inverts `--object-names`. This flag allows + the output to be more easily parsed by commands such as + linkgit:git-cat-file[1]. + --filter=<filter-spec>:: Only useful with one of the `--objects*`; omits objects (usually blobs) from the list of printed objects. The '<filter-spec>' @@ -720,9 +892,12 @@ or units. n may be zero. The suffixes k, m, and g can be used to name units in KiB, MiB, or GiB. For example, 'blob:limit=1k' is the same as 'blob:limit=1024'. + +The form '--filter=object:type=(tag|commit|tree|blob)' omits all objects +which are not of the requested type. ++ The form '--filter=sparse:oid=<blob-ish>' uses a sparse-checkout specification contained in the blob (or blob-expression) '<blob-ish>' -to omit blobs that would not be not required for a sparse checkout on +to omit blobs that would not be required for a sparse checkout on the requested refs. + The form '--filter=tree:<depth>' omits all blobs and trees whose depth @@ -738,10 +913,31 @@ explicitly-given commit or tree. Note that the form '--filter=sparse:path=<path>' that wants to read from an arbitrary path on the filesystem has been dropped for security reasons. ++ +Multiple '--filter=' flags can be specified to combine filters. Only +objects which are accepted by every filter are included. ++ +The form '--filter=combine:<filter1>+<filter2>+...<filterN>' can also be +used to combined several filters, but this is harder than just repeating +the '--filter' flag and is usually not necessary. Filters are joined by +'{plus}' and individual filters are %-encoded (i.e. URL-encoded). +Besides the '{plus}' and '%' characters, the following characters are +reserved and also must be encoded: `~!@#$^&*()[]{}\;",<>?`+'`+ +as well as all characters with ASCII code <= `0x20`, which includes +space and newline. ++ +Other arbitrary characters can also be encoded. For instance, +'combine:tree:3+blob:none' and 'combine:tree%3A3+blob%3Anone' are +equivalent. --no-filter:: Turn off any previous `--filter=` argument. +--filter-provided-objects:: + Filter the list of explicitly provided objects, which would otherwise + always be printed even if they did not match any of the filters. Only + useful with `--filter=`. + --filter-print-omitted:: Only useful with `--filter=`; prints a list of the objects omitted by the filter. Object IDs are prefixed with a ``~'' character. @@ -783,7 +979,9 @@ endif::git-rev-list[] --do-walk:: Overrides a previous `--no-walk`. +endif::git-shortlog[] +ifndef::git-shortlog[] Commit Formatting ~~~~~~~~~~~~~~~~~ @@ -866,6 +1064,14 @@ ifdef::git-rev-list[] --header:: Print the contents of the commit in raw-format; each record is separated with a NUL character. + +--no-commit-header:: + Suppress the header line containing "commit" and the object ID printed before + the specified format. This has no effect on the built-in formats; only custom + formats are affected. + +--commit-header:: + Overrides a previous `--no-commit-header`. endif::git-rev-list[] --parents:: @@ -939,46 +1145,4 @@ ifdef::git-rev-list[] counts and print the count for equivalent commits separated by a tab. endif::git-rev-list[] - -ifndef::git-rev-list[] -Diff Formatting -~~~~~~~~~~~~~~~ - -Listed below are options that control the formatting of diff output. -Some of them are specific to linkgit:git-rev-list[1], however other diff -options may be given. See linkgit:git-diff-files[1] for more options. - --c:: - With this option, diff output for a merge commit - shows the differences from each of the parents to the merge result - simultaneously instead of showing pairwise diff between a parent - and the result one at a time. Furthermore, it lists only files - which were modified from all parents. - ---cc:: - This flag implies the `-c` option and further compresses the - patch output by omitting uninteresting hunks whose contents in - the parents have only two variants and the merge result picks - one of them without modification. - ---combined-all-paths:: - This flag causes combined diffs (used for merge commits) to - list the name of the file from all parents. It thus only has - effect when -c or --cc are specified, and is likely only - useful if filename changes are detected (i.e. when either - rename or copy detection have been requested). - --m:: - This flag makes the merge commits show the full diff like - regular commits; for each merge parent, a separate log entry - and diff is generated. An exception is that only diff against - the first parent is shown when `--first-parent` option is given; - in that case, the output represents the changes the merge - brought _into_ the then-current branch. - --r:: - Show recursive diffs. - --t:: - Show the tree objects in the diff output. This implies `-r`. -endif::git-rev-list[] +endif::git-shortlog[] diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index 82c1e5754e..f5f17b65a1 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -115,7 +115,7 @@ Here's an example to make it more clear: ------------------------------ $ git config push.default current $ git config remote.pushdefault myfork -$ git checkout -b mybranch origin/master +$ git switch -c mybranch origin/master $ git rev-parse --symbolic-full-name @{upstream} refs/remotes/origin/master @@ -233,7 +233,7 @@ G H I J A = = A^0 B = A^ = A^1 = A~1 - C = A^2 = A^2 + C = = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 @@ -254,9 +254,15 @@ specifying a single revision, using the notation described in the previous section, means the set of commits `reachable` from the given commit. +Specifying several revisions means the set of commits reachable from +any of the given commits. + A commit's reachable set is the commit itself and the commits in its ancestry chain. +There are several notations to specify a set of connected commits +(called a "revision range"), illustrated below. + Commit Exclusions ~~~~~~~~~~~~~~~~~ @@ -291,6 +297,26 @@ is a shorthand for 'HEAD..origin' and asks "What did the origin do since I forked from them?" Note that '..' would mean 'HEAD..HEAD' which is an empty range that is both reachable and unreachable from HEAD. +Commands that are specifically designed to take two distinct ranges +(e.g. "git range-diff R1 R2" to compare two ranges) do exist, but +they are exceptions. Unless otherwise noted, all "git" commands +that operate on a set of commits work on a single revision range. +In other words, writing two "two-dot range notation" next to each +other, e.g. + + $ git log A..B C..D + +does *not* specify two revision ranges for most commands. Instead +it will name a single connected set of commits, i.e. those that are +reachable from either B or D but are reachable from neither A or C. +In a linear history like this: + + ---A---B---o---o---C---D + +because A and B are reachable from C, the revision range specified +by these two dotted ranges is a single commit D. + + Other <rev>{caret} Parent Shorthand Notations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Three other shorthands exist, particularly useful for merge commits, diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt index 5a57c4a407..3bceb56474 100644 --- a/Documentation/sequencer.txt +++ b/Documentation/sequencer.txt @@ -3,6 +3,10 @@ `.git/sequencer`. Can be used to continue after resolving conflicts in a failed cherry-pick or revert. +--skip:: + Skip the current commit and continue with the rest of the + sequence. + --quit:: Forget about the current operation in progress. Can be used to clear the sequencer state after a failed cherry-pick or diff --git a/Documentation/signoff-option.txt b/Documentation/signoff-option.txt new file mode 100644 index 0000000000..12aa2333e4 --- /dev/null +++ b/Documentation/signoff-option.txt @@ -0,0 +1,18 @@ +ifdef::git-commit[] +-s:: +endif::git-commit[] +--signoff:: +--no-signoff:: + Add a `Signed-off-by` trailer by the committer at the end of the commit + log message. The meaning of a signoff depends on the project + to which you're committing. For example, it may certify that + the committer has the rights to submit the work under the + project's license or agrees to some contributor representation, + such as a Developer Certificate of Origin. + (See http://developercertificate.org for the one used by the + Linux kernel and Git projects.) Consult the documentation or + leadership of the project to which you're contributing to + understand how the signoffs are used in that project. ++ +The --no-signoff option can be used to countermand an earlier --signoff +option on the command line. diff --git a/Documentation/technical/api-allocation-growing.txt b/Documentation/technical/api-allocation-growing.txt deleted file mode 100644 index 5a59b54844..0000000000 --- a/Documentation/technical/api-allocation-growing.txt +++ /dev/null @@ -1,39 +0,0 @@ -allocation growing API -====================== - -Dynamically growing an array using realloc() is error prone and boring. - -Define your array with: - -* a pointer (`item`) that points at the array, initialized to `NULL` - (although please name the variable based on its contents, not on its - type); - -* an integer variable (`alloc`) that keeps track of how big the current - allocation is, initialized to `0`; - -* another integer variable (`nr`) to keep track of how many elements the - array currently has, initialized to `0`. - -Then before adding `n`th element to the item, call `ALLOC_GROW(item, n, -alloc)`. This ensures that the array can hold at least `n` elements by -calling `realloc(3)` and adjusting `alloc` variable. - ------------- -sometype *item; -size_t nr; -size_t alloc - -for (i = 0; i < nr; i++) - if (we like item[i] already) - return; - -/* we did not like any existing one, so add one */ -ALLOC_GROW(item, nr + 1, alloc); -item[nr++] = value you like; ------------- - -You are responsible for updating the `nr` variable. - -If you need to specify the number of elements to allocate explicitly -then use the macro `REALLOC_ARRAY(item, alloc)` instead of `ALLOC_GROW`. diff --git a/Documentation/technical/api-argv-array.txt b/Documentation/technical/api-argv-array.txt deleted file mode 100644 index 870c8edbfb..0000000000 --- a/Documentation/technical/api-argv-array.txt +++ /dev/null @@ -1,65 +0,0 @@ -argv-array API -============== - -The argv-array API allows one to dynamically build and store -NULL-terminated lists. An argv-array maintains the invariant that the -`argv` member always points to a non-NULL array, and that the array is -always NULL-terminated at the element pointed to by `argv[argc]`. This -makes the result suitable for passing to functions expecting to receive -argv from main(), or the link:api-run-command.html[run-command API]. - -The string-list API (documented in string-list.h) is similar, but cannot be -used for these purposes; instead of storing a straight string pointer, -it contains an item structure with a `util` field that is not compatible -with the traditional argv interface. - -Each `argv_array` manages its own memory. Any strings pushed into the -array are duplicated, and all memory is freed by argv_array_clear(). - -Data Structures ---------------- - -`struct argv_array`:: - - A single array. This should be initialized by assignment from - `ARGV_ARRAY_INIT`, or by calling `argv_array_init`. The `argv` - member contains the actual array; the `argc` member contains the - number of elements in the array, not including the terminating - NULL. - -Functions ---------- - -`argv_array_init`:: - Initialize an array. This is no different than assigning from - `ARGV_ARRAY_INIT`. - -`argv_array_push`:: - Push a copy of a string onto the end of the array. - -`argv_array_pushl`:: - Push a list of strings onto the end of the array. The arguments - should be a list of `const char *` strings, terminated by a NULL - argument. - -`argv_array_pushf`:: - Format a string and push it onto the end of the array. This is a - convenience wrapper combining `strbuf_addf` and `argv_array_push`. - -`argv_array_pushv`:: - Push a null-terminated array of strings onto the end of the array. - -`argv_array_pop`:: - Remove the final element from the array. If there are no - elements in the array, do nothing. - -`argv_array_clear`:: - Free all memory associated with the array and return it to the - initial, empty state. - -`argv_array_detach`:: - Disconnect the `argv` member from the `argv_array` struct and - return it. The caller is responsible for freeing the memory used - by the array, and by the strings it references. After detaching, - the `argv_array` is in a reinitialized state and can be pushed - into again. diff --git a/Documentation/technical/api-config.txt b/Documentation/technical/api-config.txt deleted file mode 100644 index 7d20716c32..0000000000 --- a/Documentation/technical/api-config.txt +++ /dev/null @@ -1,319 +0,0 @@ -config API -========== - -The config API gives callers a way to access Git configuration files -(and files which have the same syntax). See linkgit:git-config[1] for a -discussion of the config file syntax. - -General Usage -------------- - -Config files are parsed linearly, and each variable found is passed to a -caller-provided callback function. The callback function is responsible -for any actions to be taken on the config option, and is free to ignore -some options. It is not uncommon for the configuration to be parsed -several times during the run of a Git program, with different callbacks -picking out different variables useful to themselves. - -A config callback function takes three parameters: - -- the name of the parsed variable. This is in canonical "flat" form: the - section, subsection, and variable segments will be separated by dots, - and the section and variable segments will be all lowercase. E.g., - `core.ignorecase`, `diff.SomeType.textconv`. - -- the value of the found variable, as a string. If the variable had no - value specified, the value will be NULL (typically this means it - should be interpreted as boolean true). - -- a void pointer passed in by the caller of the config API; this can - contain callback-specific data - -A config callback should return 0 for success, or -1 if the variable -could not be parsed properly. - -Basic Config Querying ---------------------- - -Most programs will simply want to look up variables in all config files -that Git knows about, using the normal precedence rules. To do this, -call `git_config` with a callback function and void data pointer. - -`git_config` will read all config sources in order of increasing -priority. Thus a callback should typically overwrite previously-seen -entries with new ones (e.g., if both the user-wide `~/.gitconfig` and -repo-specific `.git/config` contain `color.ui`, the config machinery -will first feed the user-wide one to the callback, and then the -repo-specific one; by overwriting, the higher-priority repo-specific -value is left at the end). - -The `config_with_options` function lets the caller examine config -while adjusting some of the default behavior of `git_config`. It should -almost never be used by "regular" Git code that is looking up -configuration variables. It is intended for advanced callers like -`git-config`, which are intentionally tweaking the normal config-lookup -process. It takes two extra parameters: - -`config_source`:: -If this parameter is non-NULL, it specifies the source to parse for -configuration, rather than looking in the usual files. See `struct -git_config_source` in `config.h` for details. Regular `git_config` defaults -to `NULL`. - -`opts`:: -Specify options to adjust the behavior of parsing config files. See `struct -config_options` in `config.h` for details. As an example: regular `git_config` -sets `opts.respect_includes` to `1` by default. - -Reading Specific Files ----------------------- - -To read a specific file in git-config format, use -`git_config_from_file`. This takes the same callback and data parameters -as `git_config`. - -Querying For Specific Variables -------------------------------- - -For programs wanting to query for specific variables in a non-callback -manner, the config API provides two functions `git_config_get_value` -and `git_config_get_value_multi`. They both read values from an internal -cache generated previously from reading the config files. - -`int git_config_get_value(const char *key, const char **value)`:: - - Finds the highest-priority value for the configuration variable `key`, - stores the pointer to it in `value` and returns 0. When the - configuration variable `key` is not found, returns 1 without touching - `value`. The caller should not free or modify `value`, as it is owned - by the cache. - -`const struct string_list *git_config_get_value_multi(const char *key)`:: - - Finds and returns the value list, sorted in order of increasing priority - for the configuration variable `key`. When the configuration variable - `key` is not found, returns NULL. The caller should not free or modify - the returned pointer, as it is owned by the cache. - -`void git_config_clear(void)`:: - - Resets and invalidates the config cache. - -The config API also provides type specific API functions which do conversion -as well as retrieval for the queried variable, including: - -`int git_config_get_int(const char *key, int *dest)`:: - - Finds and parses the value to an integer for the configuration variable - `key`. Dies on error; otherwise, stores the value of the parsed integer in - `dest` and returns 0. When the configuration variable `key` is not found, - returns 1 without touching `dest`. - -`int git_config_get_ulong(const char *key, unsigned long *dest)`:: - - Similar to `git_config_get_int` but for unsigned longs. - -`int git_config_get_bool(const char *key, int *dest)`:: - - Finds and parses the value into a boolean value, for the configuration - variable `key` respecting keywords like "true" and "false". Integer - values are converted into true/false values (when they are non-zero or - zero, respectively). Other values cause a die(). If parsing is successful, - stores the value of the parsed result in `dest` and returns 0. When the - configuration variable `key` is not found, returns 1 without touching - `dest`. - -`int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest)`:: - - Similar to `git_config_get_bool`, except that integers are copied as-is, - and `is_bool` flag is unset. - -`int git_config_get_maybe_bool(const char *key, int *dest)`:: - - Similar to `git_config_get_bool`, except that it returns -1 on error - rather than dying. - -`int git_config_get_string_const(const char *key, const char **dest)`:: - - Allocates and copies the retrieved string into the `dest` parameter for - the configuration variable `key`; if NULL string is given, prints an - error message and returns -1. When the configuration variable `key` is - not found, returns 1 without touching `dest`. - -`int git_config_get_string(const char *key, char **dest)`:: - - Similar to `git_config_get_string_const`, except that retrieved value - copied into the `dest` parameter is a mutable string. - -`int git_config_get_pathname(const char *key, const char **dest)`:: - - Similar to `git_config_get_string`, but expands `~` or `~user` into - the user's home directory when found at the beginning of the path. - -`git_die_config(const char *key, const char *err, ...)`:: - - First prints the error message specified by the caller in `err` and then - dies printing the line number and the file name of the highest priority - value for the configuration variable `key`. - -`void git_die_config_linenr(const char *key, const char *filename, int linenr)`:: - - Helper function which formats the die error message according to the - parameters entered. Used by `git_die_config()`. It can be used by callers - handling `git_config_get_value_multi()` to print the correct error message - for the desired value. - -See test-config.c for usage examples. - -Value Parsing Helpers ---------------------- - -To aid in parsing string values, the config API provides callbacks with -a number of helper functions, including: - -`git_config_int`:: -Parse the string to an integer, including unit factors. Dies on error; -otherwise, returns the parsed result. - -`git_config_ulong`:: -Identical to `git_config_int`, but for unsigned longs. - -`git_config_bool`:: -Parse a string into a boolean value, respecting keywords like "true" and -"false". Integer values are converted into true/false values (when they -are non-zero or zero, respectively). Other values cause a die(). If -parsing is successful, the return value is the result. - -`git_config_bool_or_int`:: -Same as `git_config_bool`, except that integers are returned as-is, and -an `is_bool` flag is unset. - -`git_parse_maybe_bool`:: -Same as `git_config_bool`, except that it returns -1 on error rather -than dying. - -`git_config_string`:: -Allocates and copies the value string into the `dest` parameter; if no -string is given, prints an error message and returns -1. - -`git_config_pathname`:: -Similar to `git_config_string`, but expands `~` or `~user` into the -user's home directory when found at the beginning of the path. - -Include Directives ------------------- - -By default, the config parser does not respect include directives. -However, a caller can use the special `git_config_include` wrapper -callback to support them. To do so, you simply wrap your "real" callback -function and data pointer in a `struct config_include_data`, and pass -the wrapper to the regular config-reading functions. For example: - -------------------------------------------- -int read_file_with_include(const char *file, config_fn_t fn, void *data) -{ - struct config_include_data inc = CONFIG_INCLUDE_INIT; - inc.fn = fn; - inc.data = data; - return git_config_from_file(git_config_include, file, &inc); -} -------------------------------------------- - -`git_config` respects includes automatically. The lower-level -`git_config_from_file` does not. - -Custom Configsets ------------------ - -A `config_set` can be used to construct an in-memory cache for -config-like files that the caller specifies (i.e., files like `.gitmodules`, -`~/.gitconfig` etc.). For example, - ----------------------------------------- -struct config_set gm_config; -git_configset_init(&gm_config); -int b; -/* we add config files to the config_set */ -git_configset_add_file(&gm_config, ".gitmodules"); -git_configset_add_file(&gm_config, ".gitmodules_alt"); - -if (!git_configset_get_bool(gm_config, "submodule.frotz.ignore", &b)) { - /* hack hack hack */ -} - -/* when we are done with the configset */ -git_configset_clear(&gm_config); ----------------------------------------- - -Configset API provides functions for the above mentioned work flow, including: - -`void git_configset_init(struct config_set *cs)`:: - - Initializes the config_set `cs`. - -`int git_configset_add_file(struct config_set *cs, const char *filename)`:: - - Parses the file and adds the variable-value pairs to the `config_set`, - dies if there is an error in parsing the file. Returns 0 on success, or - -1 if the file does not exist or is inaccessible. The user has to decide - if he wants to free the incomplete configset or continue using it when - the function returns -1. - -`int git_configset_get_value(struct config_set *cs, const char *key, const char **value)`:: - - Finds the highest-priority value for the configuration variable `key` - and config set `cs`, stores the pointer to it in `value` and returns 0. - When the configuration variable `key` is not found, returns 1 without - touching `value`. The caller should not free or modify `value`, as it - is owned by the cache. - -`const struct string_list *git_configset_get_value_multi(struct config_set *cs, const char *key)`:: - - Finds and returns the value list, sorted in order of increasing priority - for the configuration variable `key` and config set `cs`. When the - configuration variable `key` is not found, returns NULL. The caller - should not free or modify the returned pointer, as it is owned by the cache. - -`void git_configset_clear(struct config_set *cs)`:: - - Clears `config_set` structure, removes all saved variable-value pairs. - -In addition to above functions, the `config_set` API provides type specific -functions in the vein of `git_config_get_int` and family but with an extra -parameter, pointer to struct `config_set`. -They all behave similarly to the `git_config_get*()` family described in -"Querying For Specific Variables" above. - -Writing Config Files --------------------- - -Git gives multiple entry points in the Config API to write config values to -files namely `git_config_set_in_file` and `git_config_set`, which write to -a specific config file or to `.git/config` respectively. They both take a -key/value pair as parameter. -In the end they both call `git_config_set_multivar_in_file` which takes four -parameters: - -- the name of the file, as a string, to which key/value pairs will be written. - -- the name of key, as a string. This is in canonical "flat" form: the section, - subsection, and variable segments will be separated by dots, and the section - and variable segments will be all lowercase. - E.g., `core.ignorecase`, `diff.SomeType.textconv`. - -- the value of the variable, as a string. If value is equal to NULL, it will - remove the matching key from the config file. - -- the value regex, as a string. It will disregard key/value pairs where value - does not match. - -- a multi_replace value, as an int. If value is equal to zero, nothing or only - one matching key/value is replaced, else all matching key/values (regardless - how many) are removed, before the new pair is written. - -It returns 0 on success. - -Also, there are functions `git_config_rename_section` and -`git_config_rename_section_in_file` with parameters `old_name` and `new_name` -for renaming or removing sections in the config files. If NULL is passed -through `new_name` parameter, the section will be removed from the config file. diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt deleted file mode 100644 index 75368f26ca..0000000000 --- a/Documentation/technical/api-credentials.txt +++ /dev/null @@ -1,271 +0,0 @@ -credentials API -=============== - -The credentials API provides an abstracted way of gathering username and -password credentials from the user (even though credentials in the wider -world can take many forms, in this document the word "credential" always -refers to a username and password pair). - -This document describes two interfaces: the C API that the credential -subsystem provides to the rest of Git, and the protocol that Git uses to -communicate with system-specific "credential helpers". If you are -writing Git code that wants to look up or prompt for credentials, see -the section "C API" below. If you want to write your own helper, see -the section on "Credential Helpers" below. - -Typical setup -------------- - ------------- -+-----------------------+ -| Git code (C) |--- to server requiring ---> -| | authentication -|.......................| -| C credential API |--- prompt ---> User -+-----------------------+ - ^ | - | pipe | - | v -+-----------------------+ -| Git credential helper | -+-----------------------+ ------------- - -The Git code (typically a remote-helper) will call the C API to obtain -credential data like a login/password pair (credential_fill). The -API will itself call a remote helper (e.g. "git credential-cache" or -"git credential-store") that may retrieve credential data from a -store. If the credential helper cannot find the information, the C API -will prompt the user. Then, the caller of the API takes care of -contacting the server, and does the actual authentication. - -C API ------ - -The credential C API is meant to be called by Git code which needs to -acquire or store a credential. It is centered around an object -representing a single credential and provides three basic operations: -fill (acquire credentials by calling helpers and/or prompting the user), -approve (mark a credential as successfully used so that it can be stored -for later use), and reject (mark a credential as unsuccessful so that it -can be erased from any persistent storage). - -Data Structures -~~~~~~~~~~~~~~~ - -`struct credential`:: - - This struct represents a single username/password combination - along with any associated context. All string fields should be - heap-allocated (or NULL if they are not known or not applicable). - The meaning of the individual context fields is the same as - their counterparts in the helper protocol; see the section below - for a description of each field. -+ -The `helpers` member of the struct is a `string_list` of helpers. Each -string specifies an external helper which will be run, in order, to -either acquire or store credentials. See the section on credential -helpers below. This list is filled-in by the API functions -according to the corresponding configuration variables before -consulting helpers, so there usually is no need for a caller to -modify the helpers field at all. -+ -This struct should always be initialized with `CREDENTIAL_INIT` or -`credential_init`. - - -Functions -~~~~~~~~~ - -`credential_init`:: - - Initialize a credential structure, setting all fields to empty. - -`credential_clear`:: - - Free any resources associated with the credential structure, - returning it to a pristine initialized state. - -`credential_fill`:: - - Instruct the credential subsystem to fill the username and - password fields of the passed credential struct by first - consulting helpers, then asking the user. After this function - returns, the username and password fields of the credential are - guaranteed to be non-NULL. If an error occurs, the function will - die(). - -`credential_reject`:: - - Inform the credential subsystem that the provided credentials - have been rejected. This will cause the credential subsystem to - notify any helpers of the rejection (which allows them, for - example, to purge the invalid credentials from storage). It - will also free() the username and password fields of the - credential and set them to NULL (readying the credential for - another call to `credential_fill`). Any errors from helpers are - ignored. - -`credential_approve`:: - - Inform the credential subsystem that the provided credentials - were successfully used for authentication. This will cause the - credential subsystem to notify any helpers of the approval, so - that they may store the result to be used again. Any errors - from helpers are ignored. - -`credential_from_url`:: - - Parse a URL into broken-down credential fields. - -Example -~~~~~~~ - -The example below shows how the functions of the credential API could be -used to login to a fictitious "foo" service on a remote host: - ------------------------------------------------------------------------ -int foo_login(struct foo_connection *f) -{ - int status; - /* - * Create a credential with some context; we don't yet know the - * username or password. - */ - - struct credential c = CREDENTIAL_INIT; - c.protocol = xstrdup("foo"); - c.host = xstrdup(f->hostname); - - /* - * Fill in the username and password fields by contacting - * helpers and/or asking the user. The function will die if it - * fails. - */ - credential_fill(&c); - - /* - * Otherwise, we have a username and password. Try to use it. - */ - status = send_foo_login(f, c.username, c.password); - switch (status) { - case FOO_OK: - /* It worked. Store the credential for later use. */ - credential_accept(&c); - break; - case FOO_BAD_LOGIN: - /* Erase the credential from storage so we don't try it - * again. */ - credential_reject(&c); - break; - default: - /* - * Some other error occurred. We don't know if the - * credential is good or bad, so report nothing to the - * credential subsystem. - */ - } - - /* Free any associated resources. */ - credential_clear(&c); - - return status; -} ------------------------------------------------------------------------ - - -Credential Helpers ------------------- - -Credential helpers are programs executed by Git to fetch or save -credentials from and to long-term storage (where "long-term" is simply -longer than a single Git process; e.g., credentials may be stored -in-memory for a few minutes, or indefinitely on disk). - -Each helper is specified by a single string in the configuration -variable `credential.helper` (and others, see linkgit:git-config[1]). -The string is transformed by Git into a command to be executed using -these rules: - - 1. If the helper string begins with "!", it is considered a shell - snippet, and everything after the "!" becomes the command. - - 2. Otherwise, if the helper string begins with an absolute path, the - verbatim helper string becomes the command. - - 3. Otherwise, the string "git credential-" is prepended to the helper - string, and the result becomes the command. - -The resulting command then has an "operation" argument appended to it -(see below for details), and the result is executed by the shell. - -Here are some example specifications: - ----------------------------------------------------- -# run "git credential-foo" -foo - -# same as above, but pass an argument to the helper -foo --bar=baz - -# the arguments are parsed by the shell, so use shell -# quoting if necessary -foo --bar="whitespace arg" - -# you can also use an absolute path, which will not use the git wrapper -/path/to/my/helper --with-arguments - -# or you can specify your own shell snippet -!f() { echo "password=`cat $HOME/.secret`"; }; f ----------------------------------------------------- - -Generally speaking, rule (3) above is the simplest for users to specify. -Authors of credential helpers should make an effort to assist their -users by naming their program "git-credential-$NAME", and putting it in -the $PATH or $GIT_EXEC_PATH during installation, which will allow a user -to enable it with `git config credential.helper $NAME`. - -When a helper is executed, it will have one "operation" argument -appended to its command line, which is one of: - -`get`:: - - Return a matching credential, if any exists. - -`store`:: - - Store the credential, if applicable to the helper. - -`erase`:: - - Remove a matching credential, if any, from the helper's storage. - -The details of the credential will be provided on the helper's stdin -stream. The exact format is the same as the input/output format of the -`git credential` plumbing command (see the section `INPUT/OUTPUT -FORMAT` in linkgit:git-credential[1] for a detailed specification). - -For a `get` operation, the helper should produce a list of attributes -on stdout in the same format. A helper is free to produce a subset, or -even no values at all if it has nothing useful to provide. Any provided -attributes will overwrite those already known about by Git. If a helper -outputs a `quit` attribute with a value of `true` or `1`, no further -helpers will be consulted, nor will the user be prompted (if no -credential has been provided, the operation will then fail). - -For a `store` or `erase` operation, the helper's output is ignored. -If it fails to perform the requested operation, it may complain to -stderr to inform the user. If it does not support the requested -operation (e.g., a read-only store), it should silently ignore the -request. - -If a helper receives any other operation, it should silently ignore the -request. This leaves room for future operations to be added (older -helpers will just ignore the new requests). - -See also --------- - -linkgit:gitcredentials[7] - -linkgit:git-config[1] (See configuration variables `credential.*`) diff --git a/Documentation/technical/api-diff.txt b/Documentation/technical/api-diff.txt deleted file mode 100644 index 30fc0e9c93..0000000000 --- a/Documentation/technical/api-diff.txt +++ /dev/null @@ -1,174 +0,0 @@ -diff API -======== - -The diff API is for programs that compare two sets of files (e.g. two -trees, one tree and the index) and present the found difference in -various ways. The calling program is responsible for feeding the API -pairs of files, one from the "old" set and the corresponding one from -"new" set, that are different. The library called through this API is -called diffcore, and is responsible for two things. - -* finding total rewrites (`-B`), renames (`-M`) and copies (`-C`), and - changes that touch a string (`-S`), as specified by the caller. - -* outputting the differences in various formats, as specified by the - caller. - -Calling sequence ----------------- - -* Prepare `struct diff_options` to record the set of diff options, and - then call `repo_diff_setup()` to initialize this structure. This - sets up the vanilla default. - -* Fill in the options structure to specify desired output format, rename - detection, etc. `diff_opt_parse()` can be used to parse options given - from the command line in a way consistent with existing git-diff - family of programs. - -* Call `diff_setup_done()`; this inspects the options set up so far for - internal consistency and make necessary tweaking to it (e.g. if - textual patch output was asked, recursive behaviour is turned on); - the callback set_default in diff_options can be used to tweak this more. - -* As you find different pairs of files, call `diff_change()` to feed - modified files, `diff_addremove()` to feed created or deleted files, - or `diff_unmerge()` to feed a file whose state is 'unmerged' to the - API. These are thin wrappers to a lower-level `diff_queue()` function - that is flexible enough to record any of these kinds of changes. - -* Once you finish feeding the pairs of files, call `diffcore_std()`. - This will tell the diffcore library to go ahead and do its work. - -* Calling `diff_flush()` will produce the output. - - -Data structures ---------------- - -* `struct diff_filespec` - -This is the internal representation for a single file (blob). It -records the blob object name (if known -- for a work tree file it -typically is a NUL SHA-1), filemode and pathname. This is what the -`diff_addremove()`, `diff_change()` and `diff_unmerge()` synthesize and -feed `diff_queue()` function with. - -* `struct diff_filepair` - -This records a pair of `struct diff_filespec`; the filespec for a file -in the "old" set (i.e. preimage) is called `one`, and the filespec for a -file in the "new" set (i.e. postimage) is called `two`. A change that -represents file creation has NULL in `one`, and file deletion has NULL -in `two`. - -A `filepair` starts pointing at `one` and `two` that are from the same -filename, but `diffcore_std()` can break pairs and match component -filespecs with other filespecs from a different filepair to form new -filepair. This is called 'rename detection'. - -* `struct diff_queue` - -This is a collection of filepairs. Notable members are: - -`queue`:: - - An array of pointers to `struct diff_filepair`. This - dynamically grows as you add filepairs; - -`alloc`:: - - The allocated size of the `queue` array; - -`nr`:: - - The number of elements in the `queue` array. - - -* `struct diff_options` - -This describes the set of options the calling program wants to affect -the operation of diffcore library with. - -Notable members are: - -`output_format`:: - The output format used when `diff_flush()` is run. - -`context`:: - Number of context lines to generate in patch output. - -`break_opt`, `detect_rename`, `rename-score`, `rename_limit`:: - Affects the way detection logic for complete rewrites, renames - and copies. - -`abbrev`:: - Number of hexdigits to abbreviate raw format output to. - -`pickaxe`:: - A constant string (can and typically does contain newlines to - look for a block of text, not just a single line) to filter out - the filepairs that do not change the number of strings contained - in its preimage and postimage of the diff_queue. - -`flags`:: - This is mostly a collection of boolean options that affects the - operation, but some do not have anything to do with the diffcore - library. - -`touched_flags`:: - Records whether a flag has been changed due to user request - (rather than just set/unset by default). - -`set_default`:: - Callback which allows tweaking the options in diff_setup_done(). - -BINARY, TEXT;; - Affects the way how a file that is seemingly binary is treated. - -FULL_INDEX;; - Tells the patch output format not to use abbreviated object - names on the "index" lines. - -FIND_COPIES_HARDER;; - Tells the diffcore library that the caller is feeding unchanged - filepairs to allow copies from unmodified files be detected. - -COLOR_DIFF;; - Output should be colored. - -COLOR_DIFF_WORDS;; - Output is a colored word-diff. - -NO_INDEX;; - Tells diff-files that the input is not tracked files but files - in random locations on the filesystem. - -ALLOW_EXTERNAL;; - Tells output routine that it is Ok to call user specified patch - output routine. Plumbing disables this to ensure stable output. - -QUIET;; - Do not show any output. - -REVERSE_DIFF;; - Tells the library that the calling program is feeding the - filepairs reversed; `one` is two, and `two` is one. - -EXIT_WITH_STATUS;; - For communication between the calling program and the options - parser; tell the calling program to signal the presence of - difference using program exit code. - -HAS_CHANGES;; - Internal; used for optimization to see if there is any change. - -SILENT_ON_REMOVE;; - Affects if diff-files shows removed files. - -RECURSIVE, TREE_IN_RECURSIVE;; - Tells if tree traversal done by tree-diff should recursively - descend into a tree object pair that are different in preimage - and postimage set. - -(JC) diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt deleted file mode 100644 index 5abb8e8b1f..0000000000 --- a/Documentation/technical/api-directory-listing.txt +++ /dev/null @@ -1,130 +0,0 @@ -directory listing API -===================== - -The directory listing API is used to enumerate paths in the work tree, -optionally taking `.git/info/exclude` and `.gitignore` files per -directory into account. - -Data structure --------------- - -`struct dir_struct` structure is used to pass directory traversal -options to the library and to record the paths discovered. A single -`struct dir_struct` is used regardless of whether or not the traversal -recursively descends into subdirectories. - -The notable options are: - -`exclude_per_dir`:: - - The name of the file to be read in each directory for excluded - files (typically `.gitignore`). - -`flags`:: - - A bit-field of options: - -`DIR_SHOW_IGNORED`::: - - Return just ignored files in `entries[]`, not untracked - files. This flag is mutually exclusive with - `DIR_SHOW_IGNORED_TOO`. - -`DIR_SHOW_IGNORED_TOO`::: - - Similar to `DIR_SHOW_IGNORED`, but return ignored files in - `ignored[]` in addition to untracked files in - `entries[]`. This flag is mutually exclusive with - `DIR_SHOW_IGNORED`. - -`DIR_KEEP_UNTRACKED_CONTENTS`::: - - Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if this is set, the - untracked contents of untracked directories are also returned in - `entries[]`. - -`DIR_SHOW_IGNORED_TOO_MODE_MATCHING`::: - - Only has meaning if `DIR_SHOW_IGNORED_TOO` is also set; if - this is set, returns ignored files and directories that match - an exclude pattern. If a directory matches an exclude pattern, - then the directory is returned and the contained paths are - not. A directory that does not match an exclude pattern will - not be returned even if all of its contents are ignored. In - this case, the contents are returned as individual entries. -+ -If this is set, files and directories that explicitly match an ignore -pattern are reported. Implicitly ignored directories (directories that -do not match an ignore pattern, but whose contents are all ignored) -are not reported, instead all of the contents are reported. - -`DIR_COLLECT_IGNORED`::: - - Special mode for git-add. Return ignored files in `ignored[]` and - untracked files in `entries[]`. Only returns ignored files that match - pathspec exactly (no wildcards). Does not recurse into ignored - directories. - -`DIR_SHOW_OTHER_DIRECTORIES`::: - - Include a directory that is not tracked. - -`DIR_HIDE_EMPTY_DIRECTORIES`::: - - Do not include a directory that is not tracked and is empty. - -`DIR_NO_GITLINKS`::: - - If set, recurse into a directory that looks like a Git - directory. Otherwise it is shown as a directory. - -The result of the enumeration is left in these fields: - -`entries[]`:: - - An array of `struct dir_entry`, each element of which describes - a path. - -`nr`:: - - The number of members in `entries[]` array. - -`alloc`:: - - Internal use; keeps track of allocation of `entries[]` array. - -`ignored[]`:: - - An array of `struct dir_entry`, used for ignored paths with the - `DIR_SHOW_IGNORED_TOO` and `DIR_COLLECT_IGNORED` flags. - -`ignored_nr`:: - - The number of members in `ignored[]` array. - -Calling sequence ----------------- - -Note: index may be looked at for .gitignore files that are CE_SKIP_WORKTREE -marked. If you to exclude files, make sure you have loaded index first. - -* Prepare `struct dir_struct dir` and clear it with `memset(&dir, 0, - sizeof(dir))`. - -* To add single exclude pattern, call `add_exclude_list()` and then - `add_exclude()`. - -* To add patterns from a file (e.g. `.git/info/exclude`), call - `add_excludes_from_file()` , and/or set `dir.exclude_per_dir`. A - short-hand function `setup_standard_excludes()` can be used to set - up the standard set of exclude settings. - -* Set options described in the Data Structure section above. - -* Call `read_directory()`. - -* Use `dir.entries[]`. - -* Call `clear_directory()` when none of the contained elements are no longer in use. - -(JC) diff --git a/Documentation/technical/api-error-handling.txt b/Documentation/technical/api-error-handling.txt index ceeedd485c..8be4f4d0d6 100644 --- a/Documentation/technical/api-error-handling.txt +++ b/Documentation/technical/api-error-handling.txt @@ -1,8 +1,11 @@ Error reporting in git ====================== -`die`, `usage`, `error`, and `warning` report errors of various -kinds. +`BUG`, `die`, `usage`, `error`, and `warning` report errors of +various kinds. + +- `BUG` is for failed internal assertions that should never happen, + i.e. a bug in git itself. - `die` is for fatal application errors. It prints a message to the user and exits with status 128. @@ -20,6 +23,9 @@ kinds. without running into too many problems. Like `error`, it returns -1 after reporting the situation to the caller. +These reports will be logged via the trace2 facility. See the "error" +event in link:api-trace2.txt[trace2 API]. + Customizable error handlers --------------------------- diff --git a/Documentation/technical/api-gitattributes.txt b/Documentation/technical/api-gitattributes.txt deleted file mode 100644 index 45f0df600f..0000000000 --- a/Documentation/technical/api-gitattributes.txt +++ /dev/null @@ -1,154 +0,0 @@ -gitattributes API -================= - -gitattributes mechanism gives a uniform way to associate various -attributes to set of paths. - - -Data Structure --------------- - -`struct git_attr`:: - - An attribute is an opaque object that is identified by its name. - Pass the name to `git_attr()` function to obtain the object of - this type. The internal representation of this structure is - of no interest to the calling programs. The name of the - attribute can be retrieved by calling `git_attr_name()`. - -`struct attr_check_item`:: - - This structure represents one attribute and its value. - -`struct attr_check`:: - - This structure represents a collection of `attr_check_item`. - It is passed to `git_check_attr()` function, specifying the - attributes to check, and receives their values. - - -Attribute Values ----------------- - -An attribute for a path can be in one of four states: Set, Unset, -Unspecified or set to a string, and `.value` member of `struct -attr_check_item` records it. There are three macros to check these: - -`ATTR_TRUE()`:: - - Returns true if the attribute is Set for the path. - -`ATTR_FALSE()`:: - - Returns true if the attribute is Unset for the path. - -`ATTR_UNSET()`:: - - Returns true if the attribute is Unspecified for the path. - -If none of the above returns true, `.value` member points at a string -value of the attribute for the path. - - -Querying Specific Attributes ----------------------------- - -* Prepare `struct attr_check` using attr_check_initl() - function, enumerating the names of attributes whose values you are - interested in, terminated with a NULL pointer. Alternatively, an - empty `struct attr_check` can be prepared by calling - `attr_check_alloc()` function and then attributes you want to - ask about can be added to it with `attr_check_append()` - function. - -* Call `git_check_attr()` to check the attributes for the path. - -* Inspect `attr_check` structure to see how each of the - attribute in the array is defined for the path. - - -Example -------- - -To see how attributes "crlf" and "ident" are set for different paths. - -. Prepare a `struct attr_check` with two elements (because - we are checking two attributes): - ------------- -static struct attr_check *check; -static void setup_check(void) -{ - if (check) - return; /* already done */ - check = attr_check_initl("crlf", "ident", NULL); -} ------------- - -. Call `git_check_attr()` with the prepared `struct attr_check`: - ------------- - const char *path; - - setup_check(); - git_check_attr(path, check); ------------- - -. Act on `.value` member of the result, left in `check->items[]`: - ------------- - const char *value = check->items[0].value; - - if (ATTR_TRUE(value)) { - The attribute is Set, by listing only the name of the - attribute in the gitattributes file for the path. - } else if (ATTR_FALSE(value)) { - The attribute is Unset, by listing the name of the - attribute prefixed with a dash - for the path. - } else if (ATTR_UNSET(value)) { - The attribute is neither set nor unset for the path. - } else if (!strcmp(value, "input")) { - If none of ATTR_TRUE(), ATTR_FALSE(), or ATTR_UNSET() is - true, the value is a string set in the gitattributes - file for the path by saying "attr=value". - } else if (... other check using value as string ...) { - ... - } ------------- - -To see how attributes in argv[] are set for different paths, only -the first step in the above would be different. - ------------- -static struct attr_check *check; -static void setup_check(const char **argv) -{ - check = attr_check_alloc(); - while (*argv) { - struct git_attr *attr = git_attr(*argv); - attr_check_append(check, attr); - argv++; - } -} ------------- - - -Querying All Attributes ------------------------ - -To get the values of all attributes associated with a file: - -* Prepare an empty `attr_check` structure by calling - `attr_check_alloc()`. - -* Call `git_all_attrs()`, which populates the `attr_check` - with the attributes attached to the path. - -* Iterate over the `attr_check.items[]` array to examine - the attribute names and values. The name of the attribute - described by an `attr_check.items[]` object can be retrieved via - `git_attr_name(check->items[i].attr)`. (Please note that no items - will be returned for unset attributes, so `ATTR_UNSET()` will return - false for all returned `attr_check.items[]` objects.) - -* Free the `attr_check` struct by calling `attr_check_free()`. diff --git a/Documentation/technical/api-grep.txt b/Documentation/technical/api-grep.txt deleted file mode 100644 index a69cc8964d..0000000000 --- a/Documentation/technical/api-grep.txt +++ /dev/null @@ -1,8 +0,0 @@ -grep API -======== - -Talk about <grep.h>, things like: - -* grep_buffer() - -(JC) diff --git a/Documentation/technical/api-history-graph.txt b/Documentation/technical/api-history-graph.txt deleted file mode 100644 index d0d1707c8c..0000000000 --- a/Documentation/technical/api-history-graph.txt +++ /dev/null @@ -1,173 +0,0 @@ -history graph API -================= - -The graph API is used to draw a text-based representation of the commit -history. The API generates the graph in a line-by-line fashion. - -Functions ---------- - -Core functions: - -* `graph_init()` creates a new `struct git_graph` - -* `graph_update()` moves the graph to a new commit. - -* `graph_next_line()` outputs the next line of the graph into a strbuf. It - does not add a terminating newline. - -* `graph_padding_line()` outputs a line of vertical padding in the graph. It - is similar to `graph_next_line()`, but is guaranteed to never print the line - containing the current commit. Where `graph_next_line()` would print the - commit line next, `graph_padding_line()` prints a line that simply extends - all branch lines downwards one row, leaving their positions unchanged. - -* `graph_is_commit_finished()` determines if the graph has output all lines - necessary for the current commit. If `graph_update()` is called before all - lines for the current commit have been printed, the next call to - `graph_next_line()` will output an ellipsis, to indicate that a portion of - the graph was omitted. - -The following utility functions are wrappers around `graph_next_line()` and -`graph_is_commit_finished()`. They always print the output to stdout. -They can all be called with a NULL graph argument, in which case no graph -output will be printed. - -* `graph_show_commit()` calls `graph_next_line()` and - `graph_is_commit_finished()` until one of them return non-zero. This prints - all graph lines up to, and including, the line containing this commit. - Output is printed to stdout. The last line printed does not contain a - terminating newline. - -* `graph_show_oneline()` calls `graph_next_line()` and prints the result to - stdout. The line printed does not contain a terminating newline. - -* `graph_show_padding()` calls `graph_padding_line()` and prints the result to - stdout. The line printed does not contain a terminating newline. - -* `graph_show_remainder()` calls `graph_next_line()` until - `graph_is_commit_finished()` returns non-zero. Output is printed to stdout. - The last line printed does not contain a terminating newline. Returns 1 if - output was printed, and 0 if no output was necessary. - -* `graph_show_strbuf()` prints the specified strbuf to stdout, prefixing all - lines but the first with a graph line. The caller is responsible for - ensuring graph output for the first line has already been printed to stdout. - (This can be done with `graph_show_commit()` or `graph_show_oneline()`.) If - a NULL graph is supplied, the strbuf is printed as-is. - -* `graph_show_commit_msg()` is similar to `graph_show_strbuf()`, but it also - prints the remainder of the graph, if more lines are needed after the strbuf - ends. It is better than directly calling `graph_show_strbuf()` followed by - `graph_show_remainder()` since it properly handles buffers that do not end in - a terminating newline. The output printed by `graph_show_commit_msg()` will - end in a newline if and only if the strbuf ends in a newline. - -Data structure --------------- -`struct git_graph` is an opaque data type used to store the current graph -state. - -Calling sequence ----------------- - -* Create a `struct git_graph` by calling `graph_init()`. When using the - revision walking API, this is done automatically by `setup_revisions()` if - the '--graph' option is supplied. - -* Use the revision walking API to walk through a group of contiguous commits. - The `get_revision()` function automatically calls `graph_update()` each time - it is invoked. - -* For each commit, call `graph_next_line()` repeatedly, until - `graph_is_commit_finished()` returns non-zero. Each call to - `graph_next_line()` will output a single line of the graph. The resulting - lines will not contain any newlines. `graph_next_line()` returns 1 if the - resulting line contains the current commit, or 0 if this is merely a line - needed to adjust the graph before or after the current commit. This return - value can be used to determine where to print the commit summary information - alongside the graph output. - -Limitations ------------ - -* `graph_update()` must be called with commits in topological order. It should - not be called on a commit if it has already been invoked with an ancestor of - that commit, or the graph output will be incorrect. - -* `graph_update()` must be called on a contiguous group of commits. If - `graph_update()` is called on a particular commit, it should later be called - on all parents of that commit. Parents must not be skipped, or the graph - output will appear incorrect. -+ -`graph_update()` may be used on a pruned set of commits only if the parent list -has been rewritten so as to include only ancestors from the pruned set. - -* The graph API does not currently support reverse commit ordering. In - order to implement reverse ordering, the graphing API needs an - (efficient) mechanism to find the children of a commit. - -Sample usage ------------- - ------------- -struct commit *commit; -struct git_graph *graph = graph_init(opts); - -while ((commit = get_revision(opts)) != NULL) { - while (!graph_is_commit_finished(graph)) - { - struct strbuf sb; - int is_commit_line; - - strbuf_init(&sb, 0); - is_commit_line = graph_next_line(graph, &sb); - fputs(sb.buf, stdout); - - if (is_commit_line) - log_tree_commit(opts, commit); - else - putchar(opts->diffopt.line_termination); - } -} ------------- - -Sample output -------------- - -The following is an example of the output from the graph API. This output does -not include any commit summary information--callers are responsible for -outputting that information, if desired. - ------------- -* -* -* -|\ -* | -| | * -| \ \ -| \ \ -*-. \ \ -|\ \ \ \ -| | * | | -| | | | | * -| | | | | * -| | | | | * -| | | | | |\ -| | | | | | * -| * | | | | | -| | | | | * \ -| | | | | |\ | -| | | | * | | | -| | | | * | | | -* | | | | | | | -| |/ / / / / / -|/| / / / / / -* | | | | | | -|/ / / / / / -* | | | | | -| | | | | * -| | | | |/ -| | | | * ------------- diff --git a/Documentation/technical/api-merge.txt b/Documentation/technical/api-merge.txt index 9dc1bed768..487d4d83ff 100644 --- a/Documentation/technical/api-merge.txt +++ b/Documentation/technical/api-merge.txt @@ -28,77 +28,9 @@ and `diff.c` for examples. * `struct ll_merge_options` -This describes the set of options the calling program wants to affect -the operation of a low-level (single file) merge. Some options: - -`virtual_ancestor`:: - Behave as though this were part of a merge between common - ancestors in a recursive merge. - If a helper program is specified by the - `[merge "<driver>"] recursive` configuration, it will - be used (see linkgit:gitattributes[5]). - -`variant`:: - Resolve local conflicts automatically in favor - of one side or the other (as in 'git merge-file' - `--ours`/`--theirs`/`--union`). Can be `0`, - `XDL_MERGE_FAVOR_OURS`, `XDL_MERGE_FAVOR_THEIRS`, or - `XDL_MERGE_FAVOR_UNION`. - -`renormalize`:: - Resmudge and clean the "base", "theirs" and "ours" files - before merging. Use this when the merge is likely to have - overlapped with a change in smudge/clean or end-of-line - normalization rules. +Check ll-merge.h for details. Low-level (single file) merge ----------------------------- -`ll_merge`:: - - Perform a three-way single-file merge in core. This is - a thin wrapper around `xdl_merge` that takes the path and - any merge backend specified in `.gitattributes` or - `.git/info/attributes` into account. Returns 0 for a - clean merge. - -Calling sequence: - -* Prepare a `struct ll_merge_options` to record options. - If you have no special requests, skip this and pass `NULL` - as the `opts` parameter to use the default options. - -* Allocate an mmbuffer_t variable for the result. - -* Allocate and fill variables with the file's original content - and two modified versions (using `read_mmfile`, for example). - -* Call `ll_merge()`. - -* Read the merged content from `result_buf.ptr` and `result_buf.size`. - -* Release buffers when finished. A simple - `free(ancestor.ptr); free(ours.ptr); free(theirs.ptr); - free(result_buf.ptr);` will do. - -If the modifications do not merge cleanly, `ll_merge` will return a -nonzero value and `result_buf` will generally include a description of -the conflict bracketed by markers such as the traditional `<<<<<<<` -and `>>>>>>>`. - -The `ancestor_label`, `our_label`, and `their_label` parameters are -used to label the different sides of a conflict if the merge driver -supports this. - -Everything else ---------------- - -Talk about <merge-recursive.h> and merge_file(): - - - merge_trees() to merge with rename detection - - merge_recursive() for ancestor consolidation - - try_merge_command() for other strategies - - conflict format - - merge options - -(Daniel, Miklos, Stephan, JC) +Check ll-merge.h for details. diff --git a/Documentation/technical/api-object-access.txt b/Documentation/technical/api-object-access.txt deleted file mode 100644 index 5b29622d00..0000000000 --- a/Documentation/technical/api-object-access.txt +++ /dev/null @@ -1,15 +0,0 @@ -object access API -================= - -Talk about <sha1-file.c> and <object.h> family, things like - -* read_sha1_file() -* read_object_with_reference() -* has_sha1_file() -* write_sha1_file() -* pretend_object_file() -* lookup_{object,commit,tag,blob,tree} -* parse_{object,commit,tag,blob,tree} -* Use of object flags - -(JC, Shawn, Daniel, Dscho, Linus) diff --git a/Documentation/technical/api-oid-array.txt b/Documentation/technical/api-oid-array.txt deleted file mode 100644 index c97428c2c3..0000000000 --- a/Documentation/technical/api-oid-array.txt +++ /dev/null @@ -1,90 +0,0 @@ -oid-array API -============== - -The oid-array API provides storage and manipulation of sets of object -identifiers. The emphasis is on storage and processing efficiency, -making them suitable for large lists. Note that the ordering of items is -not preserved over some operations. - -Data Structures ---------------- - -`struct oid_array`:: - - A single array of object IDs. This should be initialized by - assignment from `OID_ARRAY_INIT`. The `oid` member contains - the actual data. The `nr` member contains the number of items in - the set. The `alloc` and `sorted` members are used internally, - and should not be needed by API callers. - -Functions ---------- - -`oid_array_append`:: - Add an item to the set. The object ID will be placed at the end of - the array (but note that some operations below may lose this - ordering). - -`oid_array_lookup`:: - Perform a binary search of the array for a specific object ID. - If found, returns the offset (in number of elements) of the - object ID. If not found, returns a negative integer. If the array - is not sorted, this function has the side effect of sorting it. - -`oid_array_clear`:: - Free all memory associated with the array and return it to the - initial, empty state. - -`oid_array_for_each`:: - Iterate over each element of the list, executing the callback - function for each one. Does not sort the list, so any custom - hash order is retained. If the callback returns a non-zero - value, the iteration ends immediately and the callback's - return is propagated; otherwise, 0 is returned. - -`oid_array_for_each_unique`:: - Iterate over each unique element of the list in sorted order, - but otherwise behave like `oid_array_for_each`. If the array - 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 --------- - ------------------------------------------ -int print_callback(const struct object_id *oid, - void *data) -{ - printf("%s\n", oid_to_hex(oid)); - return 0; /* always continue */ -} - -void some_func(void) -{ - struct sha1_array hashes = OID_ARRAY_INIT; - struct object_id oid; - - /* Read objects into our set */ - while (read_object_from_stdin(oid.hash)) - oid_array_append(&hashes, &oid); - - /* Check if some objects are in our set */ - while (read_object_from_stdin(oid.hash)) { - if (oid_array_lookup(&hashes, &oid) >= 0) - printf("it's in there!\n"); - - /* - * Print the unique set of objects. We could also have - * avoided adding duplicate objects in the first place, - * but we would end up re-sorting the array repeatedly. - * Instead, this will sort once and then skip duplicates - * in linear time. - */ - oid_array_for_each_unique(&hashes, print_callback, NULL); -} ------------------------------------------ diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index 2e2e7c10c6..5a60bbfa7f 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -232,9 +232,9 @@ There are some macros to easily define options: will be overwritten, so this should only be used for options where the last one specified on the command line wins. -`OPT_PASSTHRU_ARGV(short, long, &argv_array_var, arg_str, description, flags)`:: +`OPT_PASSTHRU_ARGV(short, long, &strvec_var, arg_str, description, flags)`:: Introduce an option where all instances of it on the command-line will - be reconstructed into an argv_array. This is useful when you need to + be reconstructed into a strvec. This is useful when you need to pass the command-line option, which can be specified multiple times, to another command. diff --git a/Documentation/technical/api-quote.txt b/Documentation/technical/api-quote.txt deleted file mode 100644 index e8a1bce94e..0000000000 --- a/Documentation/technical/api-quote.txt +++ /dev/null @@ -1,10 +0,0 @@ -quote API -========= - -Talk about <quote.h>, things like - -* sq_quote and unquote -* c_style quote and unquote -* quoting for foreign languages - -(JC) diff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt deleted file mode 100644 index 46c3d5c355..0000000000 --- a/Documentation/technical/api-ref-iteration.txt +++ /dev/null @@ -1,78 +0,0 @@ -ref iteration API -================= - - -Iteration of refs is done by using an iterate function which will call a -callback function for every ref. The callback function has this -signature: - - int handle_one_ref(const char *refname, const struct object_id *oid, - int flags, void *cb_data); - -There are different kinds of iterate functions which all take a -callback of this type. The callback is then called for each found ref -until the callback returns nonzero. The returned value is then also -returned by the iterate function. - -Iteration functions -------------------- - -* `head_ref()` just iterates the head ref. - -* `for_each_ref()` iterates all refs. - -* `for_each_ref_in()` iterates all refs which have a defined prefix and - strips that prefix from the passed variable refname. - -* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`, - `for_each_replace_ref()` iterate refs from the respective area. - -* `for_each_glob_ref()` iterates all refs that match the specified glob - pattern. - -* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined. - -* Use `refs_` API for accessing submodules. The submodule ref store could - be obtained with `get_submodule_ref_store()`. - -* `for_each_rawref()` can be used to learn about broken ref and symref. - -* `for_each_reflog()` iterates each reflog file. - -Submodules ----------- - -If you want to iterate the refs of a submodule you first need to add the -submodules object database. You can do this by a code-snippet like -this: - - const char *path = "path/to/submodule" - if (add_submodule_odb(path)) - die("Error submodule '%s' not populated.", path); - -`add_submodule_odb()` will return zero on success. If you -do not do this you will get an error for each ref that it does not point -to a valid object. - -Note: As a side-effect of this you can not safely assume that all -objects you lookup are available in superproject. All submodule objects -will be available the same way as the superprojects objects. - -Example: --------- - ----- -static int handle_remote_ref(const char *refname, - const unsigned char *sha1, int flags, void *cb_data) -{ - struct strbuf *output = cb_data; - strbuf_addf(output, "%s\n", refname); - return 0; -} - -... - - struct strbuf output = STRBUF_INIT; - for_each_remote_ref(handle_remote_ref, &output); - printf("%s", output.buf); ----- diff --git a/Documentation/technical/api-remote.txt b/Documentation/technical/api-remote.txt deleted file mode 100644 index f10941b2e8..0000000000 --- a/Documentation/technical/api-remote.txt +++ /dev/null @@ -1,127 +0,0 @@ -Remotes configuration API -========================= - -The API in remote.h gives access to the configuration related to -remotes. It handles all three configuration mechanisms historically -and currently used by Git, and presents the information in a uniform -fashion. Note that the code also handles plain URLs without any -configuration, giving them just the default information. - -struct remote -------------- - -`name`:: - - The user's nickname for the remote - -`url`:: - - An array of all of the url_nr URLs configured for the remote - -`pushurl`:: - - An array of all of the pushurl_nr push URLs configured for the remote - -`push`:: - - An array of refspecs configured for pushing, with - push_refspec being the literal strings, and push_refspec_nr - being the quantity. - -`fetch`:: - - An array of refspecs configured for fetching, with - fetch_refspec being the literal strings, and fetch_refspec_nr - being the quantity. - -`fetch_tags`:: - - The setting for whether to fetch tags (as a separate rule from - the configured refspecs); -1 means never to fetch tags, 0 - means to auto-follow tags based on the default heuristic, 1 - means to always auto-follow tags, and 2 means to fetch all - tags. - -`receivepack`, `uploadpack`:: - - The configured helper programs to run on the remote side, for - Git-native protocols. - -`http_proxy`:: - - The proxy to use for curl (http, https, ftp, etc.) URLs. - -`http_proxy_authmethod`:: - - The method used for authenticating against `http_proxy`. - -struct remotes can be found by name with remote_get(), and iterated -through with for_each_remote(). remote_get(NULL) will return the -default remote, given the current branch and configuration. - -struct refspec --------------- - -A struct refspec holds the parsed interpretation of a refspec. If it -will force updates (starts with a '+'), force is true. If it is a -pattern (sides end with '*') pattern is true. src and dest are the -two sides (including '*' characters if present); if there is only one -side, it is src, and dst is NULL; if sides exist but are empty (i.e., -the refspec either starts or ends with ':'), the corresponding side is -"". - -An array of strings can be parsed into an array of struct refspecs -using parse_fetch_refspec() or parse_push_refspec(). - -remote_find_tracking(), given a remote and a struct refspec with -either src or dst filled out, will fill out the other such that the -result is in the "fetch" specification for the remote (note that this -evaluates patterns and returns a single result). - -struct branch -------------- - -Note that this may end up moving to branch.h - -struct branch holds the configuration for a branch. It can be looked -up with branch_get(name) for "refs/heads/{name}", or with -branch_get(NULL) for HEAD. - -It contains: - -`name`:: - - The short name of the branch. - -`refname`:: - - The full path for the branch ref. - -`remote_name`:: - - The name of the remote listed in the configuration. - -`merge_name`:: - - An array of the "merge" lines in the configuration. - -`merge`:: - - An array of the struct refspecs used for the merge lines. That - is, merge[i]->dst is a local tracking ref which should be - merged into this branch by default. - -`merge_nr`:: - - The number of merge configurations - -branch_has_merge_config() returns true if the given branch has merge -configuration given. - -Other stuff ------------ - -There is other stuff in remote.h that is related, in general, to the -process of interacting with remotes. - -(Daniel Barkalow) diff --git a/Documentation/technical/api-revision-walking.txt b/Documentation/technical/api-revision-walking.txt deleted file mode 100644 index 03f9ea6ac4..0000000000 --- a/Documentation/technical/api-revision-walking.txt +++ /dev/null @@ -1,72 +0,0 @@ -revision walking API -==================== - -The revision walking API offers functions to build a list of revisions -and then iterate over that list. - -Calling sequence ----------------- - -The walking API has a given calling sequence: first you need to -initialize a rev_info structure, then add revisions to control what kind -of revision list do you want to get, finally you can iterate over the -revision list. - -Functions ---------- - -`repo_init_revisions`:: - - Initialize a rev_info structure with default values. The third - parameter may be NULL or can be prefix path, and then the `.prefix` - variable will be set to it. This is typically the first function you - want to call when you want to deal with a revision list. After calling - this function, you are free to customize options, like set - `.ignore_merges` to 0 if you don't want to ignore merges, and so on. See - `revision.h` for a complete list of available options. - -`add_pending_object`:: - - This function can be used if you want to add commit objects as revision - information. You can use the `UNINTERESTING` object flag to indicate if - you want to include or exclude the given commit (and commits reachable - from the given commit) from the revision list. -+ -NOTE: If you have the commits as a string list then you probably want to -use setup_revisions(), instead of parsing each string and using this -function. - -`setup_revisions`:: - - Parse revision information, filling in the `rev_info` structure, and - removing the used arguments from the argument list. Returns the number - of arguments left that weren't recognized, which are also moved to the - head of the argument list. The last parameter is used in case no - parameter given by the first two arguments. - -`prepare_revision_walk`:: - - Prepares the rev_info structure for a walk. You should check if it - returns any error (non-zero return code) and if it does not, you can - start using get_revision() to do the iteration. - -`get_revision`:: - - Takes a pointer to a `rev_info` structure and iterates over it, - returning a `struct commit *` each time you call it. The end of the - revision list is indicated by returning a NULL pointer. - -`reset_revision_walk`:: - - Reset the flags used by the revision walking api. You can use - this to do multiple sequential revision walks. - -Data structures ---------------- - -Talk about <revision.h>, things like: - -* two diff_options, one for path limiting, another for output; -* remaining functions; - -(Linus, JC, Dscho) diff --git a/Documentation/technical/api-run-command.txt b/Documentation/technical/api-run-command.txt deleted file mode 100644 index 8bf3e37f53..0000000000 --- a/Documentation/technical/api-run-command.txt +++ /dev/null @@ -1,264 +0,0 @@ -run-command API -=============== - -The run-command API offers a versatile tool to run sub-processes with -redirected input and output as well as with a modified environment -and an alternate current directory. - -A similar API offers the capability to run a function asynchronously, -which is primarily used to capture the output that the function -produces in the caller in order to process it. - - -Functions ---------- - -`child_process_init`:: - - Initialize a struct child_process variable. - -`start_command`:: - - Start a sub-process. Takes a pointer to a `struct child_process` - that specifies the details and returns pipe FDs (if requested). - See below for details. - -`finish_command`:: - - Wait for the completion of a sub-process that was started with - start_command(). - -`run_command`:: - - A convenience function that encapsulates a sequence of - start_command() followed by finish_command(). Takes a pointer - to a `struct child_process` that specifies the details. - -`run_command_v_opt`, `run_command_v_opt_cd_env`:: - - Convenience functions that encapsulate a sequence of - start_command() followed by finish_command(). The argument argv - specifies the program and its arguments. The argument opt is zero - or more of the flags `RUN_COMMAND_NO_STDIN`, `RUN_GIT_CMD`, - `RUN_COMMAND_STDOUT_TO_STDERR`, or `RUN_SILENT_EXEC_FAILURE` - that correspond to the members .no_stdin, .git_cmd, - .stdout_to_stderr, .silent_exec_failure of `struct child_process`. - The argument dir corresponds the member .dir. The argument env - corresponds to the member .env. - -`child_process_clear`:: - - Release the memory associated with the struct child_process. - Most users of the run-command API don't need to call this - function explicitly because `start_command` invokes it on - failure and `finish_command` calls it automatically already. - -The functions above do the following: - -. If a system call failed, errno is set and -1 is returned. A diagnostic - is printed. - -. If the program was not found, then -1 is returned and errno is set to - ENOENT; a diagnostic is printed only if .silent_exec_failure is 0. - -. Otherwise, the program is run. If it terminates regularly, its exit - code is returned. No diagnostic is printed, even if the exit code is - non-zero. - -. If the program terminated due to a signal, then the return value is the - signal number + 128, ie. the same value that a POSIX shell's $? would - report. A diagnostic is printed. - - -`start_async`:: - - Run a function asynchronously. Takes a pointer to a `struct - async` that specifies the details and returns a set of pipe FDs - for communication with the function. See below for details. - -`finish_async`:: - - Wait for the completion of an asynchronous function that was - started with start_async(). - -`run_hook`:: - - Run a hook. - The first argument is a pathname to an index file, or NULL - if the hook uses the default index file or no index is needed. - The second argument is the name of the hook. - The further arguments correspond to the hook arguments. - The last argument has to be NULL to terminate the arguments list. - If the hook does not exist or is not executable, the return - value will be zero. - If it is executable, the hook will be executed and the exit - status of the hook is returned. - On execution, .stdout_to_stderr and .no_stdin will be set. - (See below.) - - -Data structures ---------------- - -* `struct child_process` - -This describes the arguments, redirections, and environment of a -command to run in a sub-process. - -The caller: - -1. allocates and clears (using child_process_init() or - CHILD_PROCESS_INIT) a struct child_process variable; -2. initializes the members; -3. calls start_command(); -4. processes the data; -5. closes file descriptors (if necessary; see below); -6. calls finish_command(). - -The .argv member is set up as an array of string pointers (NULL -terminated), of which .argv[0] is the program name to run (usually -without a path). If the command to run is a git command, set argv[0] to -the command name without the 'git-' prefix and set .git_cmd = 1. - -Note that the ownership of the memory pointed to by .argv stays with the -caller, but it should survive until `finish_command` completes. If the -.argv member is NULL, `start_command` will point it at the .args -`argv_array` (so you may use one or the other, but you must use exactly -one). The memory in .args will be cleaned up automatically during -`finish_command` (or during `start_command` when it is unsuccessful). - -The members .in, .out, .err are used to redirect stdin, stdout, -stderr as follows: - -. Specify 0 to request no special redirection. No new file descriptor - is allocated. The child process simply inherits the channel from the - parent. - -. Specify -1 to have a pipe allocated; start_command() replaces -1 - by the pipe FD in the following way: - - .in: Returns the writable pipe end into which the caller writes; - the readable end of the pipe becomes the child's stdin. - - .out, .err: Returns the readable pipe end from which the caller - reads; the writable end of the pipe end becomes child's - stdout/stderr. - - The caller of start_command() must close the so returned FDs - after it has completed reading from/writing to it! - -. Specify a file descriptor > 0 to be used by the child: - - .in: The FD must be readable; it becomes child's stdin. - .out: The FD must be writable; it becomes child's stdout. - .err: The FD must be writable; it becomes child's stderr. - - The specified FD is closed by start_command(), even if it fails to - run the sub-process! - -. Special forms of redirection are available by setting these members - to 1: - - .no_stdin, .no_stdout, .no_stderr: The respective channel is - redirected to /dev/null. - - .stdout_to_stderr: stdout of the child is redirected to its - stderr. This happens after stderr is itself redirected. - So stdout will follow stderr to wherever it is - redirected. - -To modify the environment of the sub-process, specify an array of -string pointers (NULL terminated) in .env: - -. If the string is of the form "VAR=value", i.e. it contains '=' - the variable is added to the child process's environment. - -. If the string does not contain '=', it names an environment - variable that will be removed from the child process's environment. - -If the .env member is NULL, `start_command` will point it at the -.env_array `argv_array` (so you may use one or the other, but not both). -The memory in .env_array will be cleaned up automatically during -`finish_command` (or during `start_command` when it is unsuccessful). - -To specify a new initial working directory for the sub-process, -specify it in the .dir member. - -If the program cannot be found, the functions return -1 and set -errno to ENOENT. Normally, an error message is printed, but if -.silent_exec_failure is set to 1, no message is printed for this -special error condition. - - -* `struct async` - -This describes a function to run asynchronously, whose purpose is -to produce output that the caller reads. - -The caller: - -1. allocates and clears (memset(&asy, 0, sizeof(asy));) a - struct async variable; -2. initializes .proc and .data; -3. calls start_async(); -4. processes communicates with proc through .in and .out; -5. closes .in and .out; -6. calls finish_async(). - -The members .in, .out are used to provide a set of fd's for -communication between the caller and the callee as follows: - -. Specify 0 to have no file descriptor passed. The callee will - receive -1 in the corresponding argument. - -. Specify < 0 to have a pipe allocated; start_async() replaces - with the pipe FD in the following way: - - .in: Returns the writable pipe end into which the caller - writes; the readable end of the pipe becomes the function's - in argument. - - .out: Returns the readable pipe end from which the caller - reads; the writable end of the pipe becomes the function's - out argument. - - The caller of start_async() must close the returned FDs after it - has completed reading from/writing from them. - -. Specify a file descriptor > 0 to be used by the function: - - .in: The FD must be readable; it becomes the function's in. - .out: The FD must be writable; it becomes the function's out. - - The specified FD is closed by start_async(), even if it fails to - run the function. - -The function pointer in .proc has the following signature: - - int proc(int in, int out, void *data); - -. in, out specifies a set of file descriptors to which the function - must read/write the data that it needs/produces. The function - *must* close these descriptors before it returns. A descriptor - may be -1 if the caller did not configure a descriptor for that - direction. - -. data is the value that the caller has specified in the .data member - of struct async. - -. The return value of the function is 0 on success and non-zero - on failure. If the function indicates failure, finish_async() will - report failure as well. - - -There are serious restrictions on what the asynchronous function can do -because this facility is implemented by a thread in the same address -space on most platforms (when pthreads is available), but by a pipe to -a forked process otherwise: - -. It cannot change the program's state (global variables, environment, - etc.) in a way that the caller notices; in other words, .in and .out - are the only communication channels to the caller. - -. It must not change the program's state that the caller of the - facility also uses. diff --git a/Documentation/technical/api-setup.txt b/Documentation/technical/api-setup.txt deleted file mode 100644 index eb1fa9853e..0000000000 --- a/Documentation/technical/api-setup.txt +++ /dev/null @@ -1,47 +0,0 @@ -setup API -========= - -Talk about - -* setup_git_directory() -* setup_git_directory_gently() -* is_inside_git_dir() -* is_inside_work_tree() -* setup_work_tree() - -(Dscho) - -Pathspec --------- - -See glossary-context.txt for the syntax of pathspec. In memory, a -pathspec set is represented by "struct pathspec" and is prepared by -parse_pathspec(). This function takes several arguments: - -- magic_mask specifies what features that are NOT supported by the - following code. If a user attempts to use such a feature, - parse_pathspec() can reject it early. - -- flags specifies other things that the caller wants parse_pathspec to - perform. - -- prefix and args come from cmd_* functions - -parse_pathspec() helps catch unsupported features and reject them -politely. At a lower level, different pathspec-related functions may -not support the same set of features. Such pathspec-sensitive -functions are guarded with GUARD_PATHSPEC(), which will die in an -unfriendly way when an unsupported feature is requested. - -The command designers are supposed to make sure that GUARD_PATHSPEC() -never dies. They have to make sure all unsupported features are caught -by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC() -should give the designers all pathspec-sensitive codepaths and what -features they support. - -A similar process is applied when a new pathspec magic is added. The -designer lifts the GUARD_PATHSPEC restriction in the functions that -support the new magic. At the same time (s)he has to make sure this -new feature will be caught at parse_pathspec() in commands that cannot -handle the new magic in some cases. grepping parse_pathspec() should -help. diff --git a/Documentation/technical/api-sigchain.txt b/Documentation/technical/api-sigchain.txt deleted file mode 100644 index 9e1189ef01..0000000000 --- a/Documentation/technical/api-sigchain.txt +++ /dev/null @@ -1,41 +0,0 @@ -sigchain API -============ - -Code often wants to set a signal handler to clean up temporary files or -other work-in-progress when we die unexpectedly. For multiple pieces of -code to do this without conflicting, each piece of code must remember -the old value of the handler and restore it either when: - - 1. The work-in-progress is finished, and the handler is no longer - necessary. The handler should revert to the original behavior - (either another handler, SIG_DFL, or SIG_IGN). - - 2. The signal is received. We should then do our cleanup, then chain - to the next handler (or die if it is SIG_DFL). - -Sigchain is a tiny library for keeping a stack of handlers. Your handler -and installation code should look something like: - ------------------------------------------- - void clean_foo_on_signal(int sig) - { - clean_foo(); - sigchain_pop(sig); - raise(sig); - } - - void other_func() - { - sigchain_push_common(clean_foo_on_signal); - mess_up_foo(); - clean_foo(); - } ------------------------------------------- - -Handlers are given the typedef of sigchain_fun. This is the same type -that is given to signal() or sigaction(). It is perfectly reasonable to -push SIG_DFL or SIG_IGN onto the stack. - -You can sigchain_push and sigchain_pop individual signals. For -convenience, sigchain_push_common will push the handler onto the stack -for many common signals. diff --git a/Documentation/technical/api-simple-ipc.txt b/Documentation/technical/api-simple-ipc.txt new file mode 100644 index 0000000000..d79ad323e6 --- /dev/null +++ b/Documentation/technical/api-simple-ipc.txt @@ -0,0 +1,105 @@ +Simple-IPC API +============== + +The Simple-IPC API is a collection of `ipc_` prefixed library routines +and a basic communication protocol that allow an IPC-client process to +send an application-specific IPC-request message to an IPC-server +process and receive an application-specific IPC-response message. + +Communication occurs over a named pipe on Windows and a Unix domain +socket on other platforms. IPC-clients and IPC-servers rendezvous at +a previously agreed-to application-specific pathname (which is outside +the scope of this design) that is local to the computer system. + +The IPC-server routines within the server application process create a +thread pool to listen for connections and receive request messages +from multiple concurrent IPC-clients. When received, these messages +are dispatched up to the server application callbacks for handling. +IPC-server routines then incrementally relay responses back to the +IPC-client. + +The IPC-client routines within a client application process connect +to the IPC-server and send a request message and wait for a response. +When received, the response is returned back the caller. + +For example, the `fsmonitor--daemon` feature will be built as a server +application on top of the IPC-server library routines. It will have +threads watching for file system events and a thread pool waiting for +client connections. Clients, such as `git status` will request a list +of file system events since a point in time and the server will +respond with a list of changed files and directories. The formats of +the request and response are application-specific; the IPC-client and +IPC-server routines treat them as opaque byte streams. + + +Comparison with sub-process model +--------------------------------- + +The Simple-IPC mechanism differs from the existing `sub-process.c` +model (Documentation/technical/long-running-process-protocol.txt) and +used by applications like Git-LFS. In the LFS-style sub-process model +the helper is started by the foreground process, communication happens +via a pair of file descriptors bound to the stdin/stdout of the +sub-process, the sub-process only serves the current foreground +process, and the sub-process exits when the foreground process +terminates. + +In the Simple-IPC model the server is a very long-running service. It +can service many clients at the same time and has a private socket or +named pipe connection to each active client. It might be started +(on-demand) by the current client process or it might have been +started by a previous client or by the OS at boot time. The server +process is not associated with a terminal and it persists after +clients terminate. Clients do not have access to the stdin/stdout of +the server process and therefore must communicate over sockets or +named pipes. + + +Server startup and shutdown +--------------------------- + +How an application server based upon IPC-server is started is also +outside the scope of the Simple-IPC design and is a property of the +application using it. For example, the server might be started or +restarted during routine maintenance operations, or it might be +started as a system service during the system boot-up sequence, or it +might be started on-demand by a foreground Git command when needed. + +Similarly, server shutdown is a property of the application using +the simple-ipc routines. For example, the server might decide to +shutdown when idle or only upon explicit request. + + +Simple-IPC protocol +------------------- + +The Simple-IPC protocol consists of a single request message from the +client and an optional response message from the server. Both the +client and server messages are unlimited in length and are terminated +with a flush packet. + +The pkt-line routines (Documentation/technical/protocol-common.txt) +are used to simplify buffer management during message generation, +transmission, and reception. A flush packet is used to mark the end +of the message. This allows the sender to incrementally generate and +transmit the message. It allows the receiver to incrementally receive +the message in chunks and to know when they have received the entire +message. + +The actual byte format of the client request and server response +messages are application specific. The IPC layer transmits and +receives them as opaque byte buffers without any concern for the +content within. It is the job of the calling application layer to +understand the contents of the request and response messages. + + +Summary +------- + +Conceptually, the Simple-IPC protocol is similar to an HTTP REST +request. Clients connect, make an application-specific and +stateless request, receive an application-specific +response, and disconnect. It is a one round trip facility for +querying the server. The Simple-IPC routines hide the socket, +named pipe, and thread pool details and allow the application +layer to focus on the application at hand. diff --git a/Documentation/technical/api-submodule-config.txt b/Documentation/technical/api-submodule-config.txt deleted file mode 100644 index fb06089393..0000000000 --- a/Documentation/technical/api-submodule-config.txt +++ /dev/null @@ -1,66 +0,0 @@ -submodule config cache API -========================== - -The submodule config cache API allows to read submodule -configurations/information from specified revisions. Internally -information is lazily read into a cache that is used to avoid -unnecessary parsing of the same .gitmodules files. Lookups can be done by -submodule path or name. - -Usage ------ - -To initialize the cache with configurations from the worktree the caller -typically first calls `gitmodules_config()` to read values from the -worktree .gitmodules and then to overlay the local git config values -`parse_submodule_config_option()` from the config parsing -infrastructure. - -The caller can look up information about submodules by using the -`submodule_from_path()` or `submodule_from_name()` functions. They return -a `struct submodule` which contains the values. The API automatically -initializes and allocates the needed infrastructure on-demand. If the -caller does only want to lookup values from revisions the initialization -can be skipped. - -If the internal cache might grow too big or when the caller is done with -the API, all internally cached values can be freed with submodule_free(). - -Data Structures ---------------- - -`struct submodule`:: - - This structure is used to return the information about one - submodule for a certain revision. It is returned by the lookup - functions. - -Functions ---------- - -`void submodule_free(struct repository *r)`:: - - Use these to free the internally cached values. - -`int parse_submodule_config_option(const char *var, const char *value)`:: - - Can be passed to the config parsing infrastructure to parse - local (worktree) submodule configurations. - -`const struct submodule *submodule_from_path(const unsigned char *treeish_name, const char *path)`:: - - Given a tree-ish in the superproject and a path, return the - submodule that is bound at the path in the named tree. - -`const struct submodule *submodule_from_name(const unsigned char *treeish_name, const char *name)`:: - - The same as above but lookup by name. - -Whenever a submodule configuration is parsed in `parse_submodule_config_option` -via e.g. `gitmodules_config()`, it will overwrite the null_sha1 entry. -So in the normal case, when HEAD:.gitmodules is parsed first and then overlayed -with the repository configuration, the null_sha1 entry contains the local -configuration of a submodule (e.g. consolidated values from local git -configuration and the .gitmodules file in the worktree). - -For an example usage see test-submodule-config.c. diff --git a/Documentation/technical/api-trace.txt b/Documentation/technical/api-trace.txt deleted file mode 100644 index fadb5979c4..0000000000 --- a/Documentation/technical/api-trace.txt +++ /dev/null @@ -1,140 +0,0 @@ -trace API -========= - -The trace API can be used to print debug messages to stderr or a file. Trace -code is inactive unless explicitly enabled by setting `GIT_TRACE*` environment -variables. - -The trace implementation automatically adds `timestamp file:line ... \n` to -all trace messages. E.g.: - ------------- -23:59:59.123456 git.c:312 trace: built-in: git 'foo' -00:00:00.000001 builtin/foo.c:99 foo: some message ------------- - -Data Structures ---------------- - -`struct trace_key`:: - - Defines a trace key (or category). The default (for API functions that - don't take a key) is `GIT_TRACE`. -+ -E.g. to define a trace key controlled by environment variable `GIT_TRACE_FOO`: -+ ------------- -static struct trace_key trace_foo = TRACE_KEY_INIT(FOO); - -static void trace_print_foo(const char *message) -{ - trace_printf_key(&trace_foo, "%s", message); -} ------------- -+ -Note: don't use `const` as the trace implementation stores internal state in -the `trace_key` structure. - -Functions ---------- - -`int trace_want(struct trace_key *key)`:: - - Checks whether the trace key is enabled. Used to prevent expensive - string formatting before calling one of the printing APIs. - -`void trace_disable(struct trace_key *key)`:: - - Disables tracing for the specified key, even if the environment - variable was set. - -`void trace_printf(const char *format, ...)`:: -`void trace_printf_key(struct trace_key *key, const char *format, ...)`:: - - Prints a formatted message, similar to printf. - -`void trace_argv_printf(const char **argv, const char *format, ...)``:: - - Prints a formatted message, followed by a quoted list of arguments. - -`void trace_strbuf(struct trace_key *key, const struct strbuf *data)`:: - - Prints the strbuf, without additional formatting (i.e. doesn't - choke on `%` or even `\0`). - -`uint64_t getnanotime(void)`:: - - Returns nanoseconds since the epoch (01/01/1970), typically used - for performance measurements. -+ -Currently there are high precision timer implementations for Linux (using -`clock_gettime(CLOCK_MONOTONIC)`) and Windows (`QueryPerformanceCounter`). -Other platforms use `gettimeofday` as time source. - -`void trace_performance(uint64_t nanos, const char *format, ...)`:: -`void trace_performance_since(uint64_t start, const char *format, ...)`:: - - Prints the elapsed time (in nanoseconds), or elapsed time since - `start`, followed by a formatted message. Enabled via environment - variable `GIT_TRACE_PERFORMANCE`. Used for manual profiling, e.g.: -+ ------------- -uint64_t start = getnanotime(); -/* code section to measure */ -trace_performance_since(start, "foobar"); ------------- -+ ------------- -uint64_t t = 0; -for (;;) { - /* ignore */ - t -= getnanotime(); - /* code section to measure */ - t += getnanotime(); - /* ignore */ -} -trace_performance(t, "frotz"); ------------- - -Bugs & Caveats --------------- - -GIT_TRACE_* environment variables can be used to tell Git to show -trace output to its standard error stream. Git can often spawn a pager -internally to run its subcommand and send its standard output and -standard error to it. - -Because GIT_TRACE_PERFORMANCE trace is generated only at the very end -of the program with atexit(), which happens after the pager exits, it -would not work well if you send its log to the standard error output -and let Git spawn the pager at the same time. - -As a work around, you can for example use '--no-pager', or set -GIT_TRACE_PERFORMANCE to another file descriptor which is redirected -to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its -absolute path. - -For example instead of the following command which by default may not -print any performance information: - ------------- -GIT_TRACE_PERFORMANCE=2 git log -1 ------------- - -you may want to use: - ------------- -GIT_TRACE_PERFORMANCE=2 git --no-pager log -1 ------------- - -or: - ------------- -GIT_TRACE_PERFORMANCE=3 3>&2 git log -1 ------------- - -or: - ------------- -GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1 ------------- diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt index fd1e628944..b9f3198fbe 100644 --- a/Documentation/technical/api-trace2.txt +++ b/Documentation/technical/api-trace2.txt @@ -35,7 +35,7 @@ Format details are given in a later section. === The Normal Format Target The normal format target is a tradition printf format and similar -to GIT_TRACE format. This format is enabled with the `GIT_TR` +to GIT_TRACE format. This format is enabled with the `GIT_TRACE2` environment variable or the `trace2.normalTarget` system or global config setting. @@ -128,7 +128,7 @@ yields ------------ $ cat ~/log.event -{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"1","exe":"2.20.1.155.g426c96fcdb"} +{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"2","exe":"2.20.1.155.g426c96fcdb"} {"event":"start","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621027Z","file":"common-main.c","line":39,"t_abs":0.001173,"argv":["git","version"]} {"event":"cmd_name","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621122Z","file":"git.c","line":432,"name":"version","hierarchy":"version"} {"event":"exit","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621236Z","file":"git.c","line":662,"t_abs":0.001227,"code":0} @@ -142,10 +142,9 @@ system or global config value to one of the following: include::../trace2-target-values.txt[] -If the target already exists and is a directory, the traces will be -written to files (one per process) underneath the given directory. They -will be named according to the last component of the SID (optionally -followed by a counter to avoid filename collisions). +When trace files are written to a target directory, they will be named according +to the last component of the SID (optionally followed by a counter to avoid +filename collisions). == Trace2 API @@ -179,7 +178,7 @@ describe the simplified forms. == Public API -All Trace2 API functions send a messsage to all of the active +All Trace2 API functions send a message to all of the active Trace2 Targets. This section describes the set of available messages. @@ -189,261 +188,36 @@ purposes. === Basic Command Messages These are concerned with the lifetime of the overall git process. - -`void trace2_initialize_clock()`:: - - Initialize the Trace2 start clock and nothing else. This should - be called at the very top of main() to capture the process start - time and reduce startup order dependencies. - -`void trace2_initialize()`:: - - Determines if any Trace2 Targets should be enabled and - initializes the Trace2 facility. This includes setting up the - Trace2 thread local storage (TLS). -+ -This function emits a "version" message containing the version of git -and the Trace2 protocol. -+ -This function should be called from `main()` as early as possible in -the life of the process after essential process initialization. - -`int trace2_is_enabled()`:: - - Returns 1 if Trace2 is enabled (at least one target is - active). - -`void trace2_cmd_start(int argc, const char **argv)`:: - - Emits a "start" message containing the process command line - arguments. - -`int trace2_cmd_exit(int exit_code)`:: - - Emits an "exit" message containing the process exit-code and - elapsed time. -+ -Returns the exit-code. - -`void trace2_cmd_error(const char *fmt, va_list ap)`:: - - Emits an "error" message containing a formatted error message. - -`void trace2_cmd_path(const char *pathname)`:: - - Emits a "cmd_path" message with the full pathname of the - current process. +e.g: `void trace2_initialize_clock()`, `void trace2_initialize()`, +`int trace2_is_enabled()`, `void trace2_cmd_start(int argc, const char **argv)`. === Command Detail Messages These are concerned with describing the specific Git command after the command line, config, and environment are inspected. - -`void trace2_cmd_name(const char *name)`:: - - Emits a "cmd_name" message with the canonical name of the - command, for example "status" or "checkout". - -`void trace2_cmd_mode(const char *mode)`:: - - Emits a "cmd_mode" message with a qualifier name to further - describe the current git command. -+ -This message is intended to be used with git commands having multiple -major modes. For example, a "checkout" command can checkout a new -branch or it can checkout a single file, so the checkout code could -emit a cmd_mode message of "branch" or "file". - -`void trace2_cmd_alias(const char *alias, const char **argv_expansion)`:: - - Emits an "alias" message containing the alias used and the - argument expansion. - -`void trace2_def_param(const char *parameter, const char *value)`:: - - Emits a "def_param" message containing a key/value pair. -+ -This message is intended to report some global aspect of the current -command, such as a configuration setting or command line switch that -significantly affects program performance or behavior, such as -`core.abbrev`, `status.showUntrackedFiles`, or `--no-ahead-behind`. - -`void trace2_cmd_list_config()`:: - - Emits a "def_param" messages for "important" configuration - settings. -+ -The environment variable `GIT_TRACE2_CONFIG_PARAMS` or the `trace2.configParams` -config value can be set to a -list of patterns of important configuration settings, for example: -`core.*,remote.*.url`. This function will iterate over all config -settings and emit a "def_param" message for each match. - -`void trace2_cmd_set_config(const char *key, const char *value)`:: - - Emits a "def_param" message for a new or updated key/value - pair IF `key` is considered important. -+ -This is used to hook into `git_config_set()` and catch any -configuration changes and update a value previously reported by -`trace2_cmd_list_config()`. - -`void trace2_def_repo(struct repository *repo)`:: - - Registers a repository with the Trace2 layer. Assigns a - unique "repo-id" to `repo->trace2_repo_id`. -+ -Emits a "worktree" messages containing the repo-id and the worktree -pathname. -+ -Region and data messages (described later) may refer to this repo-id. -+ -The main/top-level repository will have repo-id value 1 (aka "r1"). -+ -The repo-id field is in anticipation of future in-proc submodule -repositories. +e.g: `void trace2_cmd_name(const char *name)`, +`void trace2_cmd_mode(const char *mode)`. === Child Process Messages These are concerned with the various spawned child processes, including shell scripts, git commands, editors, pagers, and hooks. -`void trace2_child_start(struct child_process *cmd)`:: - - Emits a "child_start" message containing the "child-id", - "child-argv", and "child-classification". -+ -Before calling this, set `cmd->trace2_child_class` to a name -describing the type of child process, for example "editor". -+ -This function assigns a unique "child-id" to `cmd->trace2_child_id`. -This field is used later during the "child_exit" message to associate -it with the "child_start" message. -+ -This function should be called before spawning the child process. - -`void trace2_child_exit(struct child_proess *cmd, int child_exit_code)`:: - - Emits a "child_exit" message containing the "child-id", - the child's elapsed time and exit-code. -+ -The reported elapsed time includes the process creation overhead and -time spend waiting for it to exit, so it may be slightly longer than -the time reported by the child itself. -+ -This function should be called after reaping the child process. - -`int trace2_exec(const char *exe, const char **argv)`:: - - Emits a "exec" message containing the "exec-id" and the - argv of the new process. -+ -This function should be called before calling one of the `exec()` -variants, such as `execvp()`. -+ -This function returns a unique "exec-id". This value is used later -if the exec() fails and a "exec-result" message is necessary. - -`void trace2_exec_result(int exec_id, int error_code)`:: - - Emits a "exec_result" message containing the "exec-id" - and the error code. -+ -On Unix-based systems, `exec()` does not return if successful. -This message is used to indicate that the `exec()` failed and -that the current program is continuing. +e.g: `void trace2_child_start(struct child_process *cmd)`. === Git Thread Messages These messages are concerned with Git thread usage. -`void trace2_thread_start(const char *thread_name)`:: - - Emits a "thread_start" message. -+ -The `thread_name` field should be a descriptive name, such as the -unique name of the thread-proc. A unique "thread-id" will be added -to the name to uniquely identify thread instances. -+ -Region and data messages (described later) may refer to this thread -name. -+ -This function must be called by the thread-proc of the new thread -(so that TLS data is properly initialized) and not by the caller -of `pthread_create()`. - -`void trace2_thread_exit()`:: - - Emits a "thread_exit" message containing the thread name - and the thread elapsed time. -+ -This function must be called by the thread-proc before it returns -(so that the coorect TLS data is used and cleaned up. It should -not be called by the caller of `pthread_join()`. +e.g: `void trace2_thread_start(const char *thread_name)`. === Region and Data Messages These are concerned with recording performance data -over regions or spans of code. - -`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`:: - -`void trace2_region_enter_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`:: - -`void trace2_region_enter_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`:: - - Emits a thread-relative "region_enter" message with optional - printf string. -+ -This function pushes a new region nesting stack level on the current -thread and starts a clock for the new stack frame. -+ -The `category` field is an arbitrary category name used to classify -regions by feature area, such as "status" or "index". At this time -it is only just printed along with the rest of the message. It may -be used in the future to filter messages. -+ -The `label` field is an arbitrary label used to describe the activity -being started, such as "read_recursive" or "do_read_index". -+ -The `repo` field, if set, will be used to get the "repo-id", so that -recursive oerations can be attributed to the correct repository. - -`void trace2_region_leave(const char *category, const char *label, const struct repository *repo)`:: - -`void trace2_region_leave_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`:: - -`void trace2_region_leave_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`:: +over regions or spans of code. e.g: +`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`. - Emits a thread-relative "region_leave" message with optional - printf string. -+ -This function pops the region nesting stack on the current thread -and reports the elapsed time of the stack frame. -+ -The `category`, `label`, and `repo` fields are the same as above. -The `category` and `label` do not need to match the correpsonding -"region_enter" message, but it makes the data stream easier to -understand. - -`void trace2_data_string(const char *category, const struct repository *repo, const char *key, const char * value)`:: - -`void trace2_data_intmax(const char *category, const struct repository *repo, const char *key, intmax value)`:: - -`void trace2_data_json(const char *category, const struct repository *repo, const char *key, const struct json_writer *jw)`:: - - Emits a region- and thread-relative "data" or "data_json" message. -+ -This is a key/value pair message containing information about the -current thread, region stack, and repository. This could be used -to print the number of files in a directory during a multi-threaded -recursive tree walk. - -`void trace2_printf(const char *fmt, ...)`:: - -`void trace2_printf_va(const char *fmt, va_list ap)`:: - - Emits a region- and thread-relative "printf" message. +Refer to trace2.h for details about all trace2 functions. == Trace2 Target Formats @@ -605,17 +379,35 @@ only present on the "start" and "atexit" events. ==== Event-Specific Key/Value Pairs `"version"`:: - This event gives the version of the executable and the EVENT format. + This event gives the version of the executable and the EVENT format. It + should always be the first event in a trace session. The EVENT format + version will be incremented if new event types are added, if existing + fields are removed, or if there are significant changes in + interpretation of existing events or fields. Smaller changes, such as + adding a new field to an existing event, will not require an increment + to the EVENT format version. + ------------ { "event":"version", ... - "evt":"1", # EVENT format version + "evt":"2", # EVENT format version "exe":"2.20.1.155.g426c96fcdb" # git version } ------------ +`"too_many_files"`:: + This event is written to the git-trace2-discard sentinel file if there + are too many files in the target trace directory (see the + trace2.maxFiles config option). ++ +------------ +{ + "event":"too_many_files", + ... +} +------------ + `"start"`:: This event contains the complete argv received by main(). + @@ -673,8 +465,8 @@ completed.) ------------ `"error"`:: - This event is emitted when one of the `error()`, `die()`, - or `usage()` functions are called. + This event is emitted when one of the `BUG()`, `error()`, `die()`, + `warning()`, or `usage()` functions are called. + ------------ { @@ -701,6 +493,20 @@ about specific error arguments. } ------------ +`"cmd_ancestry"`:: + This event contains the text command name for the parent (and earlier + generations of parents) of the current process, in an array ordered from + nearest parent to furthest great-grandparent. It may not be implemented + on all platforms. ++ +------------ +{ + "event":"cmd_ancestry", + ... + "ancestry":["bash","tmux: server","systemd"] +} +------------ + `"cmd_name"`:: This event contains the command name for this git process and the hierarchy of commands from parent git processes. @@ -799,7 +605,7 @@ with "?". Note that the session-id of the child process is not available to the current/spawning process, so the child's PID is reported here as a hint for post-processing. (But it is only a hint because the child -proces may be a shell script which doesn't have a session-id.) +process may be a shell script which doesn't have a session-id.) + Note that the `t_rel` field contains the observed run time in seconds for the child process (starting before the fork/exec/spawn and @@ -864,7 +670,8 @@ The "exec_id" field is a command-unique id and is only useful if the ------------ `"def_param"`:: - This event is generated to log a global parameter. + This event is generated to log a global parameter, such as a config + setting, command-line flag, or environment variable. + ------------ { @@ -1159,7 +966,7 @@ d0 | main | atexit | | 0.028809 | | + Regions may be nested. This causes messages to be indented in the PERF target, for example. -Elapsed times are relative to the start of the correpsonding nesting +Elapsed times are relative to the start of the corresponding nesting level as expected. For example, if we add region message to: + ---------------- @@ -1354,7 +1161,7 @@ d0 | main | atexit | | 0.030027 | | In this example, the preload region took 0.009122 seconds. The 7 threads took between 0.006069 and 0.008947 seconds to work on their portion of the index. Thread "th01" worked on 508 items at offset 0. Thread "th02" -worked on 508 items at offset 2032. Thread "th04" worked on 508 itemts +worked on 508 items at offset 2032. Thread "th04" worked on 508 items at offset 508. + This example also shows that thread names are assigned in a racy manner diff --git a/Documentation/technical/api-tree-walking.txt b/Documentation/technical/api-tree-walking.txt deleted file mode 100644 index bde18622a8..0000000000 --- a/Documentation/technical/api-tree-walking.txt +++ /dev/null @@ -1,147 +0,0 @@ -tree walking API -================ - -The tree walking API is used to traverse and inspect trees. - -Data Structures ---------------- - -`struct name_entry`:: - - An entry in a tree. Each entry has a sha1 identifier, pathname, and - mode. - -`struct tree_desc`:: - - A semi-opaque data structure used to maintain the current state of the - walk. -+ -* `buffer` is a pointer into the memory representation of the tree. It always -points at the current entry being visited. - -* `size` counts the number of bytes left in the `buffer`. - -* `entry` points to the current entry being visited. - -`struct traverse_info`:: - - A structure used to maintain the state of a traversal. -+ -* `prev` points to the traverse_info which was used to descend into the -current tree. If this is the top-level tree `prev` will point to -a dummy traverse_info. - -* `name` is the entry for the current tree (if the tree is a subtree). - -* `pathlen` is the length of the full path for the current tree. - -* `conflicts` can be used by callbacks to maintain directory-file conflicts. - -* `fn` is a callback called for each entry in the tree. See Traversing for more -information. - -* `data` can be anything the `fn` callback would want to use. - -* `show_all_errors` tells whether to stop at the first error or not. - -Initializing ------------- - -`init_tree_desc`:: - - Initialize a `tree_desc` and decode its first entry. The buffer and - size parameters are assumed to be the same as the buffer and size - members of `struct tree`. - -`fill_tree_descriptor`:: - - Initialize a `tree_desc` and decode its first entry given the - object ID of a tree. Returns the `buffer` member if the latter - is a valid tree identifier and NULL otherwise. - -`setup_traverse_info`:: - - Initialize a `traverse_info` given the pathname of the tree to start - traversing from. The `base` argument is assumed to be the `path` - member of the `name_entry` being recursed into unless the tree is a - top-level tree in which case the empty string ("") is used. - -Walking -------- - -`tree_entry`:: - - Visit the next entry in a tree. Returns 1 when there are more entries - left to visit and 0 when all entries have been visited. This is - commonly used in the test of a while loop. - -`tree_entry_len`:: - - Calculate the length of a tree entry's pathname. This utilizes the - memory structure of a tree entry to avoid the overhead of using a - generic strlen(). - -`update_tree_entry`:: - - Walk to the next entry in a tree. This is commonly used in conjunction - with `tree_entry_extract` to inspect the current entry. - -`tree_entry_extract`:: - - Decode the entry currently being visited (the one pointed to by - `tree_desc's` `entry` member) and return the sha1 of the entry. The - `pathp` and `modep` arguments are set to the entry's pathname and mode - respectively. - -`get_tree_entry`:: - - Find an entry in a tree given a pathname and the sha1 of a tree to - search. Returns 0 if the entry is found and -1 otherwise. The third - and fourth parameters are set to the entry's sha1 and mode - respectively. - -Traversing ----------- - -`traverse_trees`:: - - Traverse `n` number of trees in parallel. The `fn` callback member of - `traverse_info` is called once for each tree entry. - -`traverse_callback_t`:: - The arguments passed to the traverse callback are as follows: -+ -* `n` counts the number of trees being traversed. - -* `mask` has its nth bit set if something exists in the nth entry. - -* `dirmask` has its nth bit set if the nth tree's entry is a directory. - -* `entry` is an array of size `n` where the nth entry is from the nth tree. - -* `info` maintains the state of the traversal. - -+ -Returning a negative value will terminate the traversal. Otherwise the -return value is treated as an update mask. If the nth bit is set the nth tree -will be updated and if the bit is not set the nth tree entry will be the -same in the next callback invocation. - -`make_traverse_path`:: - - Generate the full pathname of a tree entry based from the root of the - traversal. For example, if the traversal has recursed into another - tree named "bar" the pathname of an entry "baz" in the "bar" - tree would be "bar/baz". - -`traverse_path_len`:: - - Calculate the length of a pathname returned by `make_traverse_path`. - This utilizes the memory structure of a tree entry to avoid the - overhead of using a generic strlen(). - -Authors -------- - -Written by Junio C Hamano <gitster@pobox.com> and Linus Torvalds -<torvalds@linux-foundation.org> diff --git a/Documentation/technical/api-xdiff-interface.txt b/Documentation/technical/api-xdiff-interface.txt deleted file mode 100644 index 6296ecad1d..0000000000 --- a/Documentation/technical/api-xdiff-interface.txt +++ /dev/null @@ -1,7 +0,0 @@ -xdiff interface API -=================== - -Talk about our calling convention to xdiff library, including -xdiff_emit_consume_fn. - -(Dscho, JC) diff --git a/Documentation/technical/bundle-format.txt b/Documentation/technical/bundle-format.txt new file mode 100644 index 0000000000..bac558d049 --- /dev/null +++ b/Documentation/technical/bundle-format.txt @@ -0,0 +1,76 @@ += Git bundle v2 format + +The Git bundle format is a format that represents both refs and Git objects. + +== Format + +We will use ABNF notation to define the Git bundle format. See +protocol-common.txt for the details. + +A v2 bundle looks like this: + +---- +bundle = signature *prerequisite *reference LF pack +signature = "# v2 git bundle" LF + +prerequisite = "-" obj-id SP comment LF +comment = *CHAR +reference = obj-id SP refname LF + +pack = ... ; packfile +---- + +A v3 bundle looks like this: + +---- +bundle = signature *capability *prerequisite *reference LF pack +signature = "# v3 git bundle" LF + +capability = "@" key ["=" value] LF +prerequisite = "-" obj-id SP comment LF +comment = *CHAR +reference = obj-id SP refname LF +key = 1*(ALPHA / DIGIT / "-") +value = *(%01-09 / %0b-FF) + +pack = ... ; packfile +---- + +== Semantics + +A Git bundle consists of several parts. + +* "Capabilities", which are only in the v3 format, indicate functionality that + the bundle requires to be read properly. + +* "Prerequisites" lists the objects that are NOT included in the bundle and the + reader of the bundle MUST already have, in order to use the data in the + bundle. The objects stored in the bundle may refer to prerequisite objects and + anything reachable from them (e.g. a tree object in the bundle can reference + a blob that is reachable from a prerequisite) and/or expressed as a delta + against prerequisite objects. + +* "References" record the tips of the history graph, iow, what the reader of the + bundle CAN "git fetch" from it. + +* "Pack" is the pack data stream "git fetch" would send, if you fetch from a + repository that has the references recorded in the "References" above into a + repository that has references pointing at the objects listed in + "Prerequisites" above. + +In the bundle format, there can be a comment following a prerequisite obj-id. +This is a comment and it has no specific meaning. The writer of the bundle MAY +put any string here. The reader of the bundle MUST ignore the comment. + +=== Note on the shallow clone and a Git bundle + +Note that the prerequisites does not represent a shallow-clone boundary. The +semantics of the prerequisites and the shallow-clone boundaries are different, +and the Git bundle v2 format cannot represent a shallow clone repository. + +== Capabilities + +Because there is no opportunity for negotiation, unknown capabilities cause 'git +bundle' to abort. The only known capability is `object-format`, which specifies +the hash algorithm in use, and can take the same values as the +`extensions.objectFormat` configuration value. diff --git a/Documentation/technical/chunk-format.txt b/Documentation/technical/chunk-format.txt new file mode 100644 index 0000000000..593614fced --- /dev/null +++ b/Documentation/technical/chunk-format.txt @@ -0,0 +1,116 @@ +Chunk-based file formats +======================== + +Some file formats in Git use a common concept of "chunks" to describe +sections of the file. This allows structured access to a large file by +scanning a small "table of contents" for the remaining data. This common +format is used by the `commit-graph` and `multi-pack-index` files. See +link:technical/pack-format.html[the `multi-pack-index` format] and +link:technical/commit-graph-format.html[the `commit-graph` format] for +how they use the chunks to describe structured data. + +A chunk-based file format begins with some header information custom to +that format. That header should include enough information to identify +the file type, format version, and number of chunks in the file. From this +information, that file can determine the start of the chunk-based region. + +The chunk-based region starts with a table of contents describing where +each chunk starts and ends. This consists of (C+1) rows of 12 bytes each, +where C is the number of chunks. Consider the following table: + + | Chunk ID (4 bytes) | Chunk Offset (8 bytes) | + |--------------------|------------------------| + | ID[0] | OFFSET[0] | + | ... | ... | + | ID[C] | OFFSET[C] | + | 0x0000 | OFFSET[C+1] | + +Each row consists of a 4-byte chunk identifier (ID) and an 8-byte offset. +Each integer is stored in network-byte order. + +The chunk identifier `ID[i]` is a label for the data stored within this +fill from `OFFSET[i]` (inclusive) to `OFFSET[i+1]` (exclusive). Thus, the +size of the `i`th chunk is equal to the difference between `OFFSET[i+1]` +and `OFFSET[i]`. This requires that the chunk data appears contiguously +in the same order as the table of contents. + +The final entry in the table of contents must be four zero bytes. This +confirms that the table of contents is ending and provides the offset for +the end of the chunk-based data. + +Note: The chunk-based format expects that the file contains _at least_ a +trailing hash after `OFFSET[C+1]`. + +Functions for working with chunk-based file formats are declared in +`chunk-format.h`. Using these methods provide extra checks that assist +developers when creating new file formats. + +Writing chunk-based file formats +-------------------------------- + +To write a chunk-based file format, create a `struct chunkfile` by +calling `init_chunkfile()` and pass a `struct hashfile` pointer. The +caller is responsible for opening the `hashfile` and writing header +information so the file format is identifiable before the chunk-based +format begins. + +Then, call `add_chunk()` for each chunk that is intended for write. This +populates the `chunkfile` with information about the order and size of +each chunk to write. Provide a `chunk_write_fn` function pointer to +perform the write of the chunk data upon request. + +Call `write_chunkfile()` to write the table of contents to the `hashfile` +followed by each of the chunks. This will verify that each chunk wrote +the expected amount of data so the table of contents is correct. + +Finally, call `free_chunkfile()` to clear the `struct chunkfile` data. The +caller is responsible for finalizing the `hashfile` by writing the trailing +hash and closing the file. + +Reading chunk-based file formats +-------------------------------- + +To read a chunk-based file format, the file must be opened as a +memory-mapped region. The chunk-format API expects that the entire file +is mapped as a contiguous memory region. + +Initialize a `struct chunkfile` pointer with `init_chunkfile(NULL)`. + +After reading the header information from the beginning of the file, +including the chunk count, call `read_table_of_contents()` to populate +the `struct chunkfile` with the list of chunks, their offsets, and their +sizes. + +Extract the data information for each chunk using `pair_chunk()` or +`read_chunk()`: + +* `pair_chunk()` assigns a given pointer with the location inside the + memory-mapped file corresponding to that chunk's offset. If the chunk + does not exist, then the pointer is not modified. + +* `read_chunk()` takes a `chunk_read_fn` function pointer and calls it + with the appropriate initial pointer and size information. The function + is not called if the chunk does not exist. Use this method to read chunks + if you need to perform immediate parsing or if you need to execute logic + based on the size of the chunk. + +After calling these methods, call `free_chunkfile()` to clear the +`struct chunkfile` data. This will not close the memory-mapped region. +Callers are expected to own that data for the timeframe the pointers into +the region are needed. + +Examples +-------- + +These file formats use the chunk-format API, and can be used as examples +for future formats: + +* *commit-graph:* see `write_commit_graph_file()` and `parse_commit_graph()` + in `commit-graph.c` for how the chunk-format API is used to write and + parse the commit-graph file format documented in + link:technical/commit-graph-format.html[the commit-graph file format]. + +* *multi-pack-index:* see `write_midx_internal()` and `load_multi_pack_index()` + in `midx.c` for how the chunk-format API is used to write and + parse the multi-pack-index file format documented in + link:technical/pack-format.html[the multi-pack-index file format]. diff --git a/Documentation/technical/commit-graph-format.txt b/Documentation/technical/commit-graph-format.txt index 16452a0504..87971c27dd 100644 --- a/Documentation/technical/commit-graph-format.txt +++ b/Documentation/technical/commit-graph-format.txt @@ -4,11 +4,7 @@ Git commit graph format The Git commit graph stores a list of commit OIDs and some associated metadata, including: -- The generation number of the commit. Commits with no parents have - generation number 1; commits with parents have generation number - one more than the maximum generation number of its parents. We - reserve zero as special, and can be used to mark a generation - number invalid or as "not computed". +- The generation number of the commit. - The root tree OID. @@ -17,6 +13,9 @@ metadata, including: - The parents of the commit, stored using positional references within the graph file. +- The Bloom filter of the commit carrying the paths that were changed between + the commit and its first parent, if requested. + These positional references are stored as unsigned 32-bit integers corresponding to the array position within the list of commit OIDs. Due to some special constants we use to track parents, we can store at most @@ -29,7 +28,7 @@ the body into "chunks" and provide a binary lookup table at the beginning of the body. The header includes certain values, such as number of chunks and hash type. -All 4-byte numbers are in network order. +All multi-byte numbers are in network byte order. HEADER: @@ -39,13 +38,19 @@ HEADER: 1-byte version number: Currently, the only valid version is 1. - 1-byte Hash Version (1 = SHA-1) - We infer the hash length (H) from this value. + 1-byte Hash Version + We infer the hash length (H) from this value: + 1 => SHA-1 + 2 => SHA-256 + If the hash type does not match the repository's hash algorithm, the + commit-graph file should be ignored with a warning presented to the + user. 1-byte number (C) of "chunks" - 1-byte (reserved for later use) - Current clients should ignore this value. + 1-byte number (B) of base commit-graphs + We infer the length (H*B) of the Base Graphs chunk + from this value. CHUNK LOOKUP: @@ -56,6 +61,9 @@ CHUNK LOOKUP: the length using the next chunk position if necessary.) Each chunk ID appears at most once. + The CHUNK LOOKUP matches the table of contents from + link:technical/chunk-format.html[the chunk-based file format]. + The remaining data in the body is described one chunk at a time, and these chunks may be given in any order. Chunks are required unless otherwise specified. @@ -73,17 +81,37 @@ CHUNK DATA: Commit Data (ID: {'C', 'D', 'A', 'T' }) (N * (H + 16) bytes) * The first H bytes are for the OID of the root tree. * The next 8 bytes are for the positions of the first two parents - of the ith commit. Stores value 0x7000000 if no parent in that + of the ith commit. Stores value 0x70000000 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 Extra Edge List chunk. - * The next 8 bytes store the generation number of the commit and + * The next 8 bytes store the topological level (generation number v1) + 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 time uses the 32 bits of the second 4 bytes, along with the lowest 2 bits of the lowest byte, storing the 33rd and 34th bit of the commit time. + Generation Data (ID: {'G', 'D', 'A', 'T' }) (N * 4 bytes) [Optional] + * This list of 4-byte values store corrected commit date offsets for the + commits, arranged in the same order as commit data chunk. + * If the corrected commit date offset cannot be stored within 31 bits, + the value has its most-significant bit on and the other bits store + the position of corrected commit date into the Generation Data Overflow + chunk. + * Generation Data chunk is present only when commit-graph file is written + by compatible versions of Git and in case of split commit-graph chains, + the topmost layer also has Generation Data chunk. + + Generation Data Overflow (ID: {'G', 'D', 'O', 'V' }) [Optional] + * This list of 8-byte values stores the corrected commit date offsets + for commits with corrected commit date offsets that cannot be + stored within 31 bits. + * Generation Data Overflow chunk is present only when Generation Data + chunk is present and atleast one corrected commit date offset cannot + be stored within 31 bits. + 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 @@ -92,6 +120,39 @@ CHUNK DATA: positions for the parents until reaching a value with the most-significant bit on. The other bits correspond to the position of the last parent. + Bloom Filter Index (ID: {'B', 'I', 'D', 'X'}) (N * 4 bytes) [Optional] + * The ith entry, BIDX[i], stores the number of bytes in all Bloom filters + from commit 0 to commit i (inclusive) in lexicographic order. The Bloom + filter for the i-th commit spans from BIDX[i-1] to BIDX[i] (plus header + length), where BIDX[-1] is 0. + * The BIDX chunk is ignored if the BDAT chunk is not present. + + Bloom Filter Data (ID: {'B', 'D', 'A', 'T'}) [Optional] + * It starts with header consisting of three unsigned 32-bit integers: + - Version of the hash algorithm being used. We currently only support + value 1 which corresponds to the 32-bit version of the murmur3 hash + implemented exactly as described in + https://en.wikipedia.org/wiki/MurmurHash#Algorithm and the double + hashing technique using seed values 0x293ae76f and 0x7e646e2 as + described in https://doi.org/10.1007/978-3-540-30494-4_26 "Bloom Filters + in Probabilistic Verification" + - The number of times a path is hashed and hence the number of bit positions + that cumulatively determine whether a file is present in the commit. + - The minimum number of bits 'b' per entry in the Bloom filter. If the filter + contains 'n' entries, then the filter size is the minimum number of 64-bit + words that contain n*b bits. + * The rest of the chunk is the concatenation of all the computed Bloom + filters for the commits in lexicographic order. + * Note: Commits with no changes or more than 512 changes have Bloom filters + of length one, with either all bits set to zero or one respectively. + * The BDAT chunk is present if and only if BIDX is present. + + Base Graphs List (ID: {'B', 'A', 'S', 'E'}) [Optional] + This list of H-byte hashes describe a set of B commit-graph files that + form a commit-graph chain. The graph position for the ith commit in this + file's OID Lookup chunk is equal to i plus the number of commits in all + base graphs. If B is non-zero, this chunk must exist. + TRAILER: H-byte HASH-checksum of all of the above. diff --git a/Documentation/technical/commit-graph.txt b/Documentation/technical/commit-graph.txt index fb53341d5e..f05e7bda1a 100644 --- a/Documentation/technical/commit-graph.txt +++ b/Documentation/technical/commit-graph.txt @@ -22,11 +22,11 @@ as "commit-graph" either in the .git/objects/info directory or in the info directory of an alternate. The commit-graph file stores the commit graph structure along with some -extra metadata to speed up graph walks. By listing commit OIDs in lexi- -cographic order, we can identify an integer position for each commit and -refer to the parents of a commit using those integer positions. We use -binary search to find initial commits and then use the integer positions -for fast lookups during the walk. +extra metadata to speed up graph walks. By listing commit OIDs in +lexicographic order, we can identify an integer position for each commit +and refer to the parents of a commit using those integer positions. We +use binary search to find initial commits and then use the integer +positions for fast lookups during the walk. A consumer may load the following info for a commit from the graph: @@ -38,14 +38,31 @@ A consumer may load the following info for a commit from the graph: Values 1-4 satisfy the requirements of parse_commit_gently(). -Define the "generation number" of a commit recursively as follows: +There are two definitions of generation number: +1. Corrected committer dates (generation number v2) +2. Topological levels (generation nummber v1) - * A commit with no parents (a root commit) has generation number one. +Define "corrected committer date" of a commit recursively as follows: - * A commit with at least one parent has generation number one more than - the largest generation number among its parents. + * A commit with no parents (a root commit) has corrected committer date + equal to its committer date. -Equivalently, the generation number of a commit A is one more than the + * A commit with at least one parent has corrected committer date equal to + the maximum of its commiter date and one more than the largest corrected + committer date among its parents. + + * As a special case, a root commit with timestamp zero has corrected commit + date of 1, to be able to distinguish it from GENERATION_NUMBER_ZERO + (that is, an uncomputed corrected commit date). + +Define the "topological level" of a commit recursively as follows: + + * A commit with no parents (a root commit) has topological level of one. + + * A commit with at least one parent has topological level one more than + the largest topological level among its parents. + +Equivalently, the topological level of a commit A is one more than the length of a longest path from A to a root commit. The recursive definition is easier to use for computation and observing the following property: @@ -60,6 +77,9 @@ is easier to use for computation and observing the following property: generation numbers, then we always expand the boundary commit with highest generation number and can easily detect the stopping condition. +The property applies to both versions of generation number, that is both +corrected committer dates and topological levels. + This property can be used to significantly reduce the time it takes to walk commits and determine topological relationships. Without generation numbers, the general heuristic is the following: @@ -67,7 +87,9 @@ numbers, the general heuristic is the following: If A and B are commits with commit time X and Y, respectively, and X < Y, then A _probably_ cannot reach B. -This heuristic is currently used whenever the computation is allowed to +In absence of corrected commit dates (for example, old versions of Git or +mixed generation graph chains), +this heuristic is currently used whenever the computation is allowed to violate topological relationships due to clock skew (such as "git log" with default order), but is not used when the topological order is required (such as merge base calculations, "git log --graph"). @@ -77,7 +99,7 @@ in the commit graph. We can treat these commits as having "infinite" generation number and walk until reaching commits with known generation number. -We use the macro GENERATION_NUMBER_INFINITY = 0xFFFFFFFF to mark commits not +We use the macro GENERATION_NUMBER_INFINITY to mark commits not in the commit-graph file. If a commit-graph file was written by a version of Git that did not compute generation numbers, then those commits will have generation number represented by the macro GENERATION_NUMBER_ZERO = 0. @@ -85,7 +107,7 @@ have generation number represented by the macro GENERATION_NUMBER_ZERO = 0. Since the commit-graph file is closed under reachability, we can guarantee the following weaker condition on all commits: - If A and B are commits with generation numbers N amd M, respectively, + If A and B are commits with generation numbers N and M, respectively, and N < M, then A cannot reach B. Note how the strict inequality differs from the inequality when we have @@ -93,12 +115,12 @@ fully-computed generation numbers. Using strict inequality may result in walking a few extra commits, but the simplicity in dealing with commits with generation number *_INFINITY or *_ZERO is valuable. -We use the macro GENERATION_NUMBER_MAX = 0x3FFFFFFF to for commits whose -generation numbers are computed to be at least this value. We limit at -this value since it is the largest value that can be stored in the -commit-graph file using the 30 bits available to generation numbers. This -presents another case where a commit can have generation number equal to -that of a parent. +We use the macro GENERATION_NUMBER_V1_MAX = 0x3FFFFFFF for commits whose +topological levels (generation number v1) are computed to be at least +this value. We limit at this value since it is the largest value that +can be stored in the commit-graph file using the 30 bits available +to topological levels. This presents another case where a commit can +have generation number equal to that of a parent. Design Details -------------- @@ -127,19 +149,239 @@ Design Details helpful for these clones, anyway. The commit-graph will not be read or written when shallow commits are present. +Commit Graphs Chains +-------------------- + +Typically, repos grow with near-constant velocity (commits per day). Over time, +the number of commits added by a fetch operation is much smaller than the +number of commits in the full history. By creating a "chain" of commit-graphs, +we enable fast writes of new commit data without rewriting the entire commit +history -- at least, most of the time. + +## File Layout + +A commit-graph chain uses multiple files, and we use a fixed naming convention +to organize these files. Each commit-graph file has a name +`$OBJDIR/info/commit-graphs/graph-{hash}.graph` where `{hash}` is the hex- +valued hash stored in the footer of that file (which is a hash of the file's +contents before that hash). For a chain of commit-graph files, a plain-text +file at `$OBJDIR/info/commit-graphs/commit-graph-chain` contains the +hashes for the files in order from "lowest" to "highest". + +For example, if the `commit-graph-chain` file contains the lines + +``` + {hash0} + {hash1} + {hash2} +``` + +then the commit-graph chain looks like the following diagram: + + +-----------------------+ + | graph-{hash2}.graph | + +-----------------------+ + | + +-----------------------+ + | | + | graph-{hash1}.graph | + | | + +-----------------------+ + | + +-----------------------+ + | | + | | + | | + | graph-{hash0}.graph | + | | + | | + | | + +-----------------------+ + +Let X0 be the number of commits in `graph-{hash0}.graph`, X1 be the number of +commits in `graph-{hash1}.graph`, and X2 be the number of commits in +`graph-{hash2}.graph`. If a commit appears in position i in `graph-{hash2}.graph`, +then we interpret this as being the commit in position (X0 + X1 + i), and that +will be used as its "graph position". The commits in `graph-{hash2}.graph` use these +positions to refer to their parents, which may be in `graph-{hash1}.graph` or +`graph-{hash0}.graph`. We can navigate to an arbitrary commit in position j by checking +its containment in the intervals [0, X0), [X0, X0 + X1), [X0 + X1, X0 + X1 + +X2). + +Each commit-graph file (except the base, `graph-{hash0}.graph`) contains data +specifying the hashes of all files in the lower layers. In the above example, +`graph-{hash1}.graph` contains `{hash0}` while `graph-{hash2}.graph` contains +`{hash0}` and `{hash1}`. + +## Merging commit-graph files + +If we only added a new commit-graph file on every write, we would run into a +linear search problem through many commit-graph files. Instead, we use a merge +strategy to decide when the stack should collapse some number of levels. + +The diagram below shows such a collapse. As a set of new commits are added, it +is determined by the merge strategy that the files should collapse to +`graph-{hash1}`. Thus, the new commits, the commits in `graph-{hash2}` and +the commits in `graph-{hash1}` should be combined into a new `graph-{hash3}` +file. + + +---------------------+ + | | + | (new commits) | + | | + +---------------------+ + | | + +-----------------------+ +---------------------+ + | graph-{hash2} |->| | + +-----------------------+ +---------------------+ + | | | + +-----------------------+ +---------------------+ + | | | | + | graph-{hash1} |->| | + | | | | + +-----------------------+ +---------------------+ + | tmp_graphXXX + +-----------------------+ + | | + | | + | | + | graph-{hash0} | + | | + | | + | | + +-----------------------+ + +During this process, the commits to write are combined, sorted and we write the +contents to a temporary file, all while holding a `commit-graph-chain.lock` +lock-file. When the file is flushed, we rename it to `graph-{hash3}` +according to the computed `{hash3}`. Finally, we write the new chain data to +`commit-graph-chain.lock`: + +``` + {hash3} + {hash0} +``` + +We then close the lock-file. + +## Merge Strategy + +When writing a set of commits that do not exist in the commit-graph stack of +height N, we default to creating a new file at level N + 1. We then decide to +merge with the Nth level if one of two conditions hold: + + 1. `--size-multiple=<X>` is specified or X = 2, and the number of commits in + level N is less than X times the number of commits in level N + 1. + + 2. `--max-commits=<C>` is specified with non-zero C and the number of commits + in level N + 1 is more than C commits. + +This decision cascades down the levels: when we merge a level we create a new +set of commits that then compares to the next level. + +The first condition bounds the number of levels to be logarithmic in the total +number of commits. The second condition bounds the total number of commits in +a `graph-{hashN}` file and not in the `commit-graph` file, preventing +significant performance issues when the stack merges and another process only +partially reads the previous stack. + +The merge strategy values (2 for the size multiple, 64,000 for the maximum +number of commits) could be extracted into config settings for full +flexibility. + +## Handling Mixed Generation Number Chains + +With the introduction of generation number v2 and generation data chunk, the +following scenario is possible: + +1. "New" Git writes a commit-graph with the corrected commit dates. +2. "Old" Git writes a split commit-graph on top without corrected commit dates. + +A naive approach of using the newest available generation number from +each layer would lead to violated expectations: the lower layer would +use corrected commit dates which are much larger than the topological +levels of the higher layer. For this reason, Git inspects the topmost +layer to see if the layer is missing corrected commit dates. In such a case +Git only uses topological level for generation numbers. + +When writing a new layer in split commit-graph, we write corrected commit +dates if the topmost layer has corrected commit dates written. This +guarantees that if a layer has corrected commit dates, all lower layers +must have corrected commit dates as well. + +When merging layers, we do not consider whether the merged layers had corrected +commit dates. Instead, the new layer will have corrected commit dates if the +layer below the new layer has corrected commit dates. + +While writing or merging layers, if the new layer is the only layer, it will +have corrected commit dates when written by compatible versions of Git. Thus, +rewriting split commit-graph as a single file (`--split=replace`) creates a +single layer with corrected commit dates. + +## Deleting graph-{hash} files + +After a new tip file is written, some `graph-{hash}` files may no longer +be part of a chain. It is important to remove these files from disk, eventually. +The main reason to delay removal is that another process could read the +`commit-graph-chain` file before it is rewritten, but then look for the +`graph-{hash}` files after they are deleted. + +To allow holding old split commit-graphs for a while after they are unreferenced, +we update the modified times of the files when they become unreferenced. Then, +we scan the `$OBJDIR/info/commit-graphs/` directory for `graph-{hash}` +files whose modified times are older than a given expiry window. This window +defaults to zero, but can be changed using command-line arguments or a config +setting. + +## Chains across multiple object directories + +In a repo with alternates, we look for the `commit-graph-chain` file starting +in the local object directory and then in each alternate. The first file that +exists defines our chain. As we look for the `graph-{hash}` files for +each `{hash}` in the chain file, we follow the same pattern for the host +directories. + +This allows commit-graphs to be split across multiple forks in a fork network. +The typical case is a large "base" repo with many smaller forks. + +As the base repo advances, it will likely update and merge its commit-graph +chain more frequently than the forks. If a fork updates their commit-graph after +the base repo, then it should "reparent" the commit-graph chain onto the new +chain in the base repo. When reading each `graph-{hash}` file, we track +the object directory containing it. During a write of a new commit-graph file, +we check for any changes in the source object directory and read the +`commit-graph-chain` file for that source and create a new file based on those +files. During this "reparent" operation, we necessarily need to collapse all +levels in the fork, as all of the files are invalid against the new base file. + +It is crucial to be careful when cleaning up "unreferenced" `graph-{hash}.graph` +files in this scenario. It falls to the user to define the proper settings for +their custom environment: + + 1. When merging levels in the base repo, the unreferenced files may still be + referenced by chains from fork repos. + + 2. The expiry time should be set to a length of time such that every fork has + time to recompute their commit-graph chain to "reparent" onto the new base + file(s). + + 3. If the commit-graph chain is updated in the base, the fork will not have + access to the new chain until its chain is updated to reference those files. + (This may change in the future [5].) + Related Links ------------- [0] https://bugs.chromium.org/p/git/issues/detail?id=8 Chromium work item for: Serialized Commit Graph -[1] https://public-inbox.org/git/20110713070517.GC18566@sigill.intra.peff.net/ +[1] https://lore.kernel.org/git/20110713070517.GC18566@sigill.intra.peff.net/ An abandoned patch that introduced generation numbers. -[2] https://public-inbox.org/git/20170908033403.q7e6dj7benasrjes@sigill.intra.peff.net/ +[2] https://lore.kernel.org/git/20170908033403.q7e6dj7benasrjes@sigill.intra.peff.net/ Discussion about generation numbers on commits and how they interact with fsck. -[3] https://public-inbox.org/git/20170908034739.4op3w4f2ma5s65ku@sigill.intra.peff.net/ +[3] https://lore.kernel.org/git/20170908034739.4op3w4f2ma5s65ku@sigill.intra.peff.net/ More discussion about generation numbers and not storing them inside commit objects. A valuable quote: @@ -151,5 +393,9 @@ Related Links commit objects (i.e., packv4 or something like the "metapacks" I proposed a few years ago)." -[4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u +[4] https://lore.kernel.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u A patch to remove the ahead-behind calculation from 'status'. + +[5] https://lore.kernel.org/git/f27db281-abad-5043-6d71-cbb083b1c877@gmail.com/ + A discussion of a "two-dimensional graph position" that can allow reading + multiple commit-graph chains at the same time. diff --git a/Documentation/technical/directory-rename-detection.txt b/Documentation/technical/directory-rename-detection.txt index 844629c8c4..029ee2cedc 100644 --- a/Documentation/technical/directory-rename-detection.txt +++ b/Documentation/technical/directory-rename-detection.txt @@ -2,9 +2,9 @@ Directory rename detection ========================== Rename detection logic in diffcore-rename that checks for renames of -individual files is aggregated and analyzed in merge-recursive for cases -where combinations of renames indicate that a full directory has been -renamed. +individual files is also aggregated there and then analyzed in either +merge-ort or merge-recursive for cases where combinations of renames +indicate that a full directory has been renamed. Scope of abilities ------------------ @@ -18,7 +18,8 @@ It is perhaps easiest to start with an example: More interesting possibilities exist, though, such as: * one side of history renames x -> z, and the other renames some file to - x/e, causing the need for the merge to do a transitive rename. + x/e, causing the need for the merge to do a transitive rename so that + the rename ends up at z/e. * one side of history renames x -> z, but also renames all files within x. For example, x/a -> z/alpha, x/b -> z/bravo, etc. @@ -35,7 +36,7 @@ More interesting possibilities exist, though, such as: directory itself contained inner directories that were renamed to yet other locations). - * combinations of the above; see t/t6043-merge-rename-directories.sh for + * combinations of the above; see t/t6423-merge-rename-directories.sh for various interesting cases. Limitations -- applicability of directory renames @@ -62,19 +63,19 @@ directory rename detection applies: Limitations -- detailed rules and testcases ------------------------------------------- -t/t6043-merge-rename-directories.sh contains extensive tests and commentary +t/t6423-merge-rename-directories.sh contains extensive tests and commentary which generate and explore the rules listed above. It also lists a few additional rules: a) If renames split a directory into two or more others, the directory with the most renames, "wins". - b) Avoid directory-rename-detection for a path, if that path is the - source of a rename on either side of a merge. - - c) Only apply implicit directory renames to directories if the other side + b) Only apply implicit directory renames to directories if the other side of history is the one doing the renaming. + c) Do not perform directory rename detection for directories which had no + new paths added to them. + Limitations -- support in different commands -------------------------------------------- @@ -87,9 +88,11 @@ directory rename detection support in: Folks have requested in the past that `git diff` detect directory renames and somehow simplify its output. It is not clear whether this would be desirable or how the output should be simplified, so this was - simply not implemented. Further, to implement this, directory rename - detection logic would need to move from merge-recursive to - diffcore-rename. + simply not implemented. Also, while diffcore-rename has most of the + logic for detecting directory renames, some of the logic is still found + within merge-ort and merge-recursive. Fully supporting directory + rename detection in diffs would require copying or moving the remaining + bits of logic to the diff machinery. * am diff --git a/Documentation/technical/hash-function-transition.txt b/Documentation/technical/hash-function-transition.txt index bc2ace2a6e..260224b033 100644 --- a/Documentation/technical/hash-function-transition.txt +++ b/Documentation/technical/hash-function-transition.txt @@ -33,16 +33,9 @@ researchers. On 23 February 2017 the SHAttered attack Git v2.13.0 and later subsequently moved to a hardened SHA-1 implementation by default, which isn't vulnerable to the SHAttered -attack. +attack, but SHA-1 is still weak. -Thus Git has in effect already migrated to a new hash that isn't SHA-1 -and doesn't share its vulnerabilities, its new hash function just -happens to produce exactly the same output for all known inputs, -except two PDFs published by the SHAttered researchers, and the new -implementation (written by those researchers) claims to detect future -cryptanalytic collision attacks. - -Regardless, it's considered prudent to move past any variant of SHA-1 +Thus it's considered prudent to move past any variant of SHA-1 to a new hash. There's no guarantee that future attacks on SHA-1 won't be published in the future, and those attacks may not have viable mitigations. @@ -57,6 +50,38 @@ SHA-1 still possesses the other properties such as fast object lookup and safe error checking, but other hash functions are equally suitable that are believed to be cryptographically secure. +Choice of Hash +-------------- +The hash to replace the hardened SHA-1 should be stronger than SHA-1 +was: we would like it to be trustworthy and useful in practice for at +least 10 years. + +Some other relevant properties: + +1. A 256-bit hash (long enough to match common security practice; not + excessively long to hurt performance and disk usage). + +2. High quality implementations should be widely available (e.g., in + OpenSSL and Apple CommonCrypto). + +3. The hash function's properties should match Git's needs (e.g. Git + requires collision and 2nd preimage resistance and does not require + length extension resistance). + +4. As a tiebreaker, the hash should be fast to compute (fortunately + many contenders are faster than SHA-1). + +There were several contenders for a successor hash to SHA-1, including +SHA-256, SHA-512/256, SHA-256x16, K12, and BLAKE2bp-256. + +In late 2018 the project picked SHA-256 as its successor hash. + +See 0ed8d8da374 (doc hash-function-transition: pick SHA-256 as +NewHash, 2018-08-04) and numerous mailing list threads at the time, +particularly the one starting at +https://lore.kernel.org/git/20180609224913.GC38834@genre.crustytoothpaste.net/ +for more information. + Goals ----- 1. The transition to SHA-256 can be done one local repository at a time. @@ -94,7 +119,7 @@ Overview -------- We introduce a new repository format extension. Repositories with this extension enabled use SHA-256 instead of SHA-1 to name their objects. -This affects both object names and object content --- both the names +This affects both object names and object content -- both the names of objects and all references to other objects within an object are switched to the new hash function. @@ -107,7 +132,7 @@ mapping to allow naming objects using either their SHA-1 and SHA-256 names interchangeably. "git cat-file" and "git hash-object" gain options to display an object -in its sha1 form and write an object given its sha1 form. This +in its SHA-1 form and write an object given its SHA-1 form. This requires all objects referenced by that object to be present in the object database so that they can be named using the appropriate name (using the bidirectional hash mapping). @@ -115,7 +140,7 @@ object database so that they can be named using the appropriate name Fetches from a SHA-1 based server convert the fetched objects into SHA-256 form and record the mapping in the bidirectional mapping table (see below for details). Pushes to a SHA-1 based server convert the -objects being pushed into sha1 form so the server does not have to be +objects being pushed into SHA-1 form so the server does not have to be aware of the hash function the client is using. Detailed Design @@ -151,38 +176,38 @@ repository extensions. Object names ~~~~~~~~~~~~ -Objects can be named by their 40 hexadecimal digit sha1-name or 64 -hexadecimal digit sha256-name, plus names derived from those (see +Objects can be named by their 40 hexadecimal digit SHA-1 name or 64 +hexadecimal digit SHA-256 name, plus names derived from those (see gitrevisions(7)). -The sha1-name of an object is the SHA-1 of the concatenation of its -type, length, a nul byte, and the object's sha1-content. This is the +The SHA-1 name of an object is the SHA-1 of the concatenation of its +type, length, a nul byte, and the object's SHA-1 content. This is the traditional <sha1> used in Git to name objects. -The sha256-name of an object is the SHA-256 of the concatenation of its -type, length, a nul byte, and the object's sha256-content. +The SHA-256 name of an object is the SHA-256 of the concatenation of its +type, length, a nul byte, and the object's SHA-256 content. Object format ~~~~~~~~~~~~~ The content as a byte sequence of a tag, commit, or tree object named -by sha1 and sha256 differ because an object named by sha256-name refers to -other objects by their sha256-names and an object named by sha1-name -refers to other objects by their sha1-names. +by SHA-1 and SHA-256 differ because an object named by SHA-256 name refers to +other objects by their SHA-256 names and an object named by SHA-1 name +refers to other objects by their SHA-1 names. -The sha256-content of an object is the same as its sha1-content, except -that objects referenced by the object are named using their sha256-names -instead of sha1-names. Because a blob object does not refer to any -other object, its sha1-content and sha256-content are the same. +The SHA-256 content of an object is the same as its SHA-1 content, except +that objects referenced by the object are named using their SHA-256 names +instead of SHA-1 names. Because a blob object does not refer to any +other object, its SHA-1 content and SHA-256 content are the same. -The format allows round-trip conversion between sha256-content and -sha1-content. +The format allows round-trip conversion between SHA-256 content and +SHA-1 content. Object storage ~~~~~~~~~~~~~~ Loose objects use zlib compression and packed objects use the packed format described in Documentation/technical/pack-format.txt, just like -today. The content that is compressed and stored uses sha256-content -instead of sha1-content. +today. The content that is compressed and stored uses SHA-256 content +instead of SHA-1 content. Pack index ~~~~~~~~~~ @@ -191,21 +216,21 @@ hash functions. They have the following format (all integers are in network byte order): - A header appears at the beginning and consists of the following: - - The 4-byte pack index signature: '\377t0c' - - 4-byte version number: 3 - - 4-byte length of the header section, including the signature and + * The 4-byte pack index signature: '\377t0c' + * 4-byte version number: 3 + * 4-byte length of the header section, including the signature and version number - - 4-byte number of objects contained in the pack - - 4-byte number of object formats in this pack index: 2 - - For each object format: - - 4-byte format identifier (e.g., 'sha1' for SHA-1) - - 4-byte length in bytes of shortened object names. This is the + * 4-byte number of objects contained in the pack + * 4-byte number of object formats in this pack index: 2 + * For each object format: + ** 4-byte format identifier (e.g., 'sha1' for SHA-1) + ** 4-byte length in bytes of shortened object names. This is the shortest possible length needed to make names in the shortened object name table unambiguous. - - 4-byte integer, recording where tables relating to this format + ** 4-byte integer, recording where tables relating to this format are stored in this index file, as an offset from the beginning. - - 4-byte offset to the trailer from the beginning of this file. - - Zero or more additional key/value pairs (4-byte key, 4-byte + * 4-byte offset to the trailer from the beginning of this file. + * Zero or more additional key/value pairs (4-byte key, 4-byte value). Only one key is supported: 'PSRC'. See the "Loose objects and unreachable objects" section for supported values and how this is used. All other keys are reserved. Readers must ignore @@ -213,37 +238,36 @@ network byte order): - Zero or more NUL bytes. This can optionally be used to improve the alignment of the full object name table below. - Tables for the first object format: - - A sorted table of shortened object names. These are prefixes of + * A sorted table of shortened object names. These are prefixes of the names of all objects in this pack file, packed together without offset values to reduce the cache footprint of the binary search for a specific object name. - - A table of full object names in pack order. This allows resolving + * A table of full object names in pack order. This allows resolving a reference to "the nth object in the pack file" (from a reachability bitmap or from the next table of another object format) to its object name. - - A table of 4-byte values mapping object name order to pack order. + * A table of 4-byte values mapping object name order to pack order. For an object in the table of sorted shortened object names, the value at the corresponding index in this table is the index in the previous table for that same object. - This can be used to look up the object in reachability bitmaps or to look up its name in another object format. - - A table of 4-byte CRC32 values of the packed object data, in the + * A table of 4-byte CRC32 values of the packed object data, in the order that the objects appear in the pack file. This is to allow compressed data to be copied directly from pack to pack during repacking without undetected data corruption. - - A table of 4-byte offset values. For an object in the table of + * A table of 4-byte offset values. For an object in the table of sorted shortened object names, the value at the corresponding index in this table indicates where that object can be found in the pack file. These are usually 31-bit pack file offsets, but large offsets are encoded as an index into the next table with the most significant bit set. - - A table of 8-byte offset entries (empty for pack files less than + * A table of 8-byte offset entries (empty for pack files less than 2 GiB). Pack files are organized with heavily used objects toward the front, so most object references should not need to refer to this table. @@ -252,10 +276,10 @@ network byte order): up to and not including the table of CRC32 values. - Zero or more NUL bytes. - The trailer consists of the following: - - A copy of the 20-byte SHA-256 checksum at the end of the + * A copy of the 20-byte SHA-256 checksum at the end of the corresponding packfile. - - 20-byte SHA-256 checksum of all of the above. + * 20-byte SHA-256 checksum of all of the above. Loose object index ~~~~~~~~~~~~~~~~~~ @@ -288,18 +312,18 @@ To remove entries (e.g. in "git pack-refs" or "git-prune"): Translation table ~~~~~~~~~~~~~~~~~ -The index files support a bidirectional mapping between sha1-names -and sha256-names. The lookup proceeds similarly to ordinary object -lookups. For example, to convert a sha1-name to a sha256-name: +The index files support a bidirectional mapping between SHA-1 names +and SHA-256 names. The lookup proceeds similarly to ordinary object +lookups. For example, to convert a SHA-1 name to a SHA-256 name: 1. Look for the object in idx files. If a match is present in the - idx's sorted list of truncated sha1-names, then: - a. Read the corresponding entry in the sha1-name order to pack + idx's sorted list of truncated SHA-1 names, then: + a. Read the corresponding entry in the SHA-1 name order to pack name order mapping. - b. Read the corresponding entry in the full sha1-name table to + b. Read the corresponding entry in the full SHA-1 name table to verify we found the right object. If it is, then - c. Read the corresponding entry in the full sha256-name table. - That is the object's sha256-name. + c. Read the corresponding entry in the full SHA-256 name table. + That is the object's SHA-256 name. 2. Check for a loose object. Read lines from loose-object-idx until we find a match. @@ -313,10 +337,10 @@ Since all operations that make new objects (e.g., "git commit") add the new objects to the corresponding index, this mapping is possible for all objects in the object store. -Reading an object's sha1-content -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The sha1-content of an object can be read by converting all sha256-names -its sha256-content references to sha1-names using the translation table. +Reading an object's SHA-1 content +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The SHA-1 content of an object can be read by converting all SHA-256 names +of its SHA-256 content references to SHA-1 names using the translation table. Fetch ~~~~~ @@ -339,7 +363,7 @@ the following steps: 1. index-pack: inflate each object in the packfile and compute its SHA-1. Objects can contain deltas in OBJ_REF_DELTA format against objects the client has locally. These objects can be looked up - using the translation table and their sha1-content read as + using the translation table and their SHA-1 content read as described above to resolve the deltas. 2. topological sort: starting at the "want"s from the negotiation phase, walk through objects in the pack and emit a list of them, @@ -348,12 +372,12 @@ the following steps: (This list only contains objects reachable from the "wants". If the pack from the server contained additional extraneous objects, then they will be discarded.) -3. convert to sha256: open a new (sha256) packfile. Read the topologically +3. convert to SHA-256: open a new SHA-256 packfile. Read the topologically sorted list just generated. For each object, inflate its - sha1-content, convert to sha256-content, and write it to the sha256 - pack. Record the new sha1<->sha256 mapping entry for use in the idx. + SHA-1 content, convert to SHA-256 content, and write it to the SHA-256 + pack. Record the new SHA-1<-->SHA-256 mapping entry for use in the idx. 4. sort: reorder entries in the new pack to match the order of objects - in the pack the server generated and include blobs. Write a sha256 idx + in the pack the server generated and include blobs. Write a SHA-256 idx file 5. clean up: remove the SHA-1 based pack file, index, and topologically sorted list obtained from the server in steps 1 @@ -378,19 +402,20 @@ experimenting to get this to perform well. Push ~~~~ Push is simpler than fetch because the objects referenced by the -pushed objects are already in the translation table. The sha1-content +pushed objects are already in the translation table. The SHA-1 content of each object being pushed can be read as described in the "Reading -an object's sha1-content" section to generate the pack written by git +an object's SHA-1 content" section to generate the pack written by git send-pack. Signed Commits ~~~~~~~~~~~~~~ We add a new field "gpgsig-sha256" to the commit object format to allow signing commits without relying on SHA-1. It is similar to the -existing "gpgsig" field. Its signed payload is the sha256-content of the +existing "gpgsig" field. Its signed payload is the SHA-256 content of the commit object with any "gpgsig" and "gpgsig-sha256" fields removed. This means commits can be signed + 1. using SHA-1 only, as in existing signed commit objects 2. using both SHA-1 and SHA-256, by using both gpgsig-sha256 and gpgsig fields. @@ -404,10 +429,11 @@ Signed Tags ~~~~~~~~~~~ We add a new field "gpgsig-sha256" to the tag object format to allow signing tags without relying on SHA-1. Its signed payload is the -sha256-content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP +SHA-256 content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP SIGNATURE-----" delimited in-body signature removed. This means tags can be signed + 1. using SHA-1 only, as in existing signed tag objects 2. using both SHA-1 and SHA-256, by using gpgsig-sha256 and an in-body signature. @@ -415,11 +441,11 @@ This means tags can be signed Mergetag embedding ~~~~~~~~~~~~~~~~~~ -The mergetag field in the sha1-content of a commit contains the -sha1-content of a tag that was merged by that commit. +The mergetag field in the SHA-1 content of a commit contains the +SHA-1 content of a tag that was merged by that commit. -The mergetag field in the sha256-content of the same commit contains the -sha256-content of the same tag. +The mergetag field in the SHA-256 content of the same commit contains the +SHA-256 content of the same tag. Submodules ~~~~~~~~~~ @@ -456,7 +482,7 @@ packfile marked as UNREACHABLE_GARBAGE (using the PSRC field; see below). To avoid the race when writing new objects referring to an about-to-be-deleted object, code paths that write new objects will need to copy any objects from UNREACHABLE_GARBAGE packs that they -refer to to new, non-UNREACHABLE_GARBAGE packs (or loose objects). +refer to new, non-UNREACHABLE_GARBAGE packs (or loose objects). UNREACHABLE_GARBAGE are then safe to delete if their creation time (as indicated by the file's mtime) is long enough ago. @@ -494,7 +520,7 @@ Caveats ------- Invalid objects ~~~~~~~~~~~~~~~ -The conversion from sha1-content to sha256-content retains any +The conversion from SHA-1 content to SHA-256 content retains any brokenness in the original object (e.g., tree entry modes encoded with leading 0, tree objects whose paths are not sorted correctly, and commit objects without an author or committer). This is a deliberate @@ -513,15 +539,15 @@ allow lifting this restriction. Alternates ~~~~~~~~~~ -For the same reason, a sha256 repository cannot borrow objects from a -sha1 repository using objects/info/alternates or +For the same reason, a SHA-256 repository cannot borrow objects from a +SHA-1 repository using objects/info/alternates or $GIT_ALTERNATE_OBJECT_REPOSITORIES. git notes ~~~~~~~~~ -The "git notes" tool annotates objects using their sha1-name as key. +The "git notes" tool annotates objects using their SHA-1 name as key. This design does not describe a way to migrate notes trees to use -sha256-names. That migration is expected to happen separately (for +SHA-256 names. That migration is expected to happen separately (for example using a file at the root of the notes tree to describe which hash it uses). @@ -531,7 +557,7 @@ Until Git protocol gains SHA-256 support, using SHA-256 based storage on public-facing Git servers is strongly discouraged. Once Git protocol gains SHA-256 support, SHA-256 based servers are likely not to support SHA-1 compatibility, to avoid what may be a very expensive -hash reencode during clone and to encourage peers to modernize. +hash re-encode during clone and to encourage peers to modernize. The design described here allows fetches by SHA-1 clients of a personal SHA-256 repository because it's not much more difficult than @@ -555,7 +581,7 @@ unclear: Git 2.12 -Does this mean Git v2.12.0 is the commit with sha1-name +Does this mean Git v2.12.0 is the commit with SHA-1 name e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7 or the commit with new-40-digit-hash-name e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7? @@ -573,7 +599,7 @@ supports four different modes of operation: convert any object names written to output to SHA-1, but store objects using SHA-256. This allows users to test the code with no visible behavior change except for performance. This allows - allows running even tests that assume the SHA-1 hash function, to + running even tests that assume the SHA-1 hash function, to sanity-check the behavior of the new mode. 2. ("early transition") Allow both SHA-1 and SHA-256 object names in @@ -598,44 +624,12 @@ The user can also explicitly specify which format to use for a particular revision specifier and for output, overriding the mode. For example: -git --output-format=sha1 log abac87a^{sha1}..f787cac^{sha256} - -Choice of Hash --------------- -In early 2005, around the time that Git was written, Xiaoyun Wang, -Yiqun Lisa Yin, and Hongbo Yu announced an attack finding SHA-1 -collisions in 2^69 operations. In August they published details. -Luckily, no practical demonstrations of a collision in full SHA-1 were -published until 10 years later, in 2017. - -Git v2.13.0 and later subsequently moved to a hardened SHA-1 -implementation by default that mitigates the SHAttered attack, but -SHA-1 is still believed to be weak. - -The hash to replace this hardened SHA-1 should be stronger than SHA-1 -was: we would like it to be trustworthy and useful in practice for at -least 10 years. - -Some other relevant properties: - -1. A 256-bit hash (long enough to match common security practice; not - excessively long to hurt performance and disk usage). - -2. High quality implementations should be widely available (e.g., in - OpenSSL and Apple CommonCrypto). - -3. The hash function's properties should match Git's needs (e.g. Git - requires collision and 2nd preimage resistance and does not require - length extension resistance). - -4. As a tiebreaker, the hash should be fast to compute (fortunately - many contenders are faster than SHA-1). - -We choose SHA-256. + git --output-format=sha1 log abac87a^{sha1}..f787cac^{sha256} Transition plan --------------- Some initial steps can be implemented independently of one another: + - adding a hash function API (vtable) - teaching fsck to tolerate the gpgsig-sha256 field - excluding gpgsig-* from the fields copied by "git commit --amend" @@ -647,10 +641,9 @@ Some initial steps can be implemented independently of one another: - introducing index v3 - adding support for the PSRC field and safer object pruning - The first user-visible change is the introduction of the objectFormat extension (without compatObjectFormat). This requires: -- implementing the loose-object-idx + - teaching fsck about this mode of operation - using the hash function API (vtable) when computing object names - signing objects and verifying signatures @@ -658,6 +651,8 @@ extension (without compatObjectFormat). This requires: repository Next comes introduction of compatObjectFormat: + +- implementing the loose-object-idx - translating object names between object formats - translating object content between object formats - generating and verifying signatures in the compat format @@ -669,10 +664,11 @@ Next comes introduction of compatObjectFormat: "Object names on the command line" above) The next step is supporting fetches and pushes to SHA-1 repositories: + - allow pushes to a repository using the compat format - generate a topologically sorted list of the SHA-1 names of fetched objects -- convert the fetched packfile to sha256 format and generate an idx +- convert the fetched packfile to SHA-256 format and generate an idx file - re-sort to match the order of objects in the fetched packfile @@ -730,10 +726,11 @@ adoption. Using hash functions in parallel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -(e.g. https://public-inbox.org/git/22708.8913.864049.452252@chiark.greenend.org.uk/ ) +(e.g. https://lore.kernel.org/git/22708.8913.864049.452252@chiark.greenend.org.uk/ ) Objects newly created would be addressed by the new hash, but inside such an object (e.g. commit) it is still possible to address objects using the old hash function. + * You cannot trust its history (needed for bisectability) in the future without further work * Maintenance burden as the number of supported hash functions grows @@ -743,36 +740,38 @@ using the old hash function. Signed objects with multiple hashes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Instead of introducing the gpgsig-sha256 field in commit and tag objects -for sha256-content based signatures, an earlier version of this design -added "hash sha256 <sha256-name>" fields to strengthen the existing -sha1-content based signatures. +for SHA-256 content based signatures, an earlier version of this design +added "hash sha256 <SHA-256 name>" fields to strengthen the existing +SHA-1 content based signatures. In other words, a single signature was used to attest to the object content using both hash functions. This had some advantages: + * Using one signature instead of two speeds up the signing process. * Having one signed payload with both hashes allows the signer to - attest to the sha1-name and sha256-name referring to the same object. + attest to the SHA-1 name and SHA-256 name referring to the same object. * All users consume the same signature. Broken signatures are likely to be detected quickly using current versions of git. However, it also came with disadvantages: -* Verifying a signed object requires access to the sha1-names of all + +* Verifying a signed object requires access to the SHA-1 names of all objects it references, even after the transition is complete and translation table is no longer needed for anything else. To support - this, the design added fields such as "hash sha1 tree <sha1-name>" - and "hash sha1 parent <sha1-name>" to the sha256-content of a signed + this, the design added fields such as "hash sha1 tree <SHA-1 name>" + and "hash sha1 parent <SHA-1 name>" to the SHA-256 content of a signed commit, complicating the conversion process. -* Allowing signed objects without a sha1 (for after the transition is +* Allowing signed objects without a SHA-1 (for after the transition is complete) complicated the design further, requiring a "nohash sha1" - field to suppress including "hash sha1" fields in the sha256-content + field to suppress including "hash sha1" fields in the SHA-256 content and signed payload. Lazily populated translation table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Some of the work of building the translation table could be deferred to push time, but that would significantly complicate and slow down pushes. -Calculating the sha1-name at object creation time at the same time it is -being streamed to disk and having its sha256-name calculated should be +Calculating the SHA-1 name at object creation time at the same time it is +being streamed to disk and having its SHA-256 name calculated should be an acceptable cost. Document History @@ -782,18 +781,19 @@ Document History bmwill@google.com, jonathantanmy@google.com, jrnieder@gmail.com, sbeller@google.com -Initial version sent to -http://public-inbox.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com +* Initial version sent to https://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com 2017-03-03 jrnieder@gmail.com Incorporated suggestions from jonathantanmy and sbeller: -* describe purpose of signed objects with each hash type -* redefine signed object verification using object content under the + +* Describe purpose of signed objects with each hash type +* Redefine signed object verification using object content under the first hash function 2017-03-06 jrnieder@gmail.com + * Use SHA3-256 instead of SHA2 (thanks, Linus and brian m. carlson).[1][2] -* Make sha3-based signatures a separate field, avoiding the need for +* Make SHA3-based signatures a separate field, avoiding the need for "hash" and "nohash" fields (thanks to peff[3]). * Add a sorting phase to fetch (thanks to Junio for noticing the need for this). @@ -805,23 +805,26 @@ Incorporated suggestions from jonathantanmy and sbeller: especially Junio). 2017-09-27 jrnieder@gmail.com, sbeller@google.com -* use placeholder NewHash instead of SHA3-256 -* describe criteria for picking a hash function. -* include a transition plan (thanks especially to Brandon Williams + +* Use placeholder NewHash instead of SHA3-256 +* Describe criteria for picking a hash function. +* Include a transition plan (thanks especially to Brandon Williams for fleshing these ideas out) -* define the translation table (thanks, Shawn Pearce[5], Jonathan +* Define the translation table (thanks, Shawn Pearce[5], Jonathan Tan, and Masaya Suzuki) -* avoid loose object overhead by packing more aggressively in +* Avoid loose object overhead by packing more aggressively in "git gc --auto" Later history: - See the history of this file in git.git for the history of subsequent - edits. This document history is no longer being maintained as it - would now be superfluous to the commit log +* See the history of this file in git.git for the history of subsequent + edits. This document history is no longer being maintained as it + would now be superfluous to the commit log + +References: -[1] http://public-inbox.org/git/CA+55aFzJtejiCjV0e43+9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com/ -[2] http://public-inbox.org/git/CA+55aFz+gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com/ -[3] http://public-inbox.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/ -[4] http://public-inbox.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net -[5] https://public-inbox.org/git/CAJo=hJtoX9=AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com/ + [1] https://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com/ + [2] https://lore.kernel.org/git/CA+55aFz+gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com/ + [3] https://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/ + [4] https://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net + [5] https://lore.kernel.org/git/CAJo=hJtoX9=AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com/ diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt index 9c5b6f0fac..96d89ea9b2 100644 --- a/Documentation/technical/http-protocol.txt +++ b/Documentation/technical/http-protocol.txt @@ -216,7 +216,7 @@ smart server reply: S: 001e# service=git-upload-pack\n S: 0000 S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n - S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n + S: 003fd049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n S: 0000 @@ -401,8 +401,9 @@ at all in the request stream: The stream is terminated by a pkt-line flush (`0000`). A single "want" or "have" command MUST have one hex formatted -SHA-1 as its value. Multiple SHA-1s MUST be sent by sending -multiple commands. +object name as its value. Multiple object names MUST be sent by sending +multiple commands. Object names MUST be given using the object format +negotiated through the `object-format` capability (default SHA-1). The `have` list is created by popping the first 32 commits from `c_pending`. Less can be supplied if `c_pending` empties. diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt index 7c4d67aa6a..65da0daaa5 100644 --- a/Documentation/technical/index-format.txt +++ b/Documentation/technical/index-format.txt @@ -3,8 +3,11 @@ Git index format == The Git index file has the following format - All binary numbers are in network byte order. Version 2 is described - here unless stated otherwise. + All binary numbers are in network byte order. + In a repository using the traditional SHA-1, checksums and object IDs + (object names) mentioned below are all computed using SHA-1. Similarly, + in SHA-256 repositories, these values are computed using SHA-256. + Version 2 is described here unless stated otherwise. - A 12-byte header consisting of @@ -23,7 +26,7 @@ Git index format Extensions are identified by signature. Optional extensions can be ignored if Git does not understand them. - Git currently supports cached tree and resolve undo extensions. + Git currently supports cache tree and resolve undo extensions. 4-byte extension signature. If the first byte is 'A'..'Z' the extension is optional and can be ignored. @@ -32,8 +35,7 @@ Git index format Extension data - - 160-bit SHA-1 over the content of the index file before this - checksum. + - Hash checksum over the content of the index file before this checksum. == Index entry @@ -42,6 +44,13 @@ Git index format localization, no special casing of directory separator '/'). Entries with the same name are sorted by their stage field. + An index entry typically represents a file. However, if sparse-checkout + is enabled in cone mode (`core.sparseCheckoutCone` is enabled) and the + `extensions.sparseIndex` extension is enabled, then the index may + contain entries for directories outside of the sparse-checkout definition. + These entries have mode `040000`, include the `SKIP_WORKTREE` bit, and + the path ends in a directory separator. + 32-bit ctime seconds, the last time a file's metadata changed this is stat(2) data @@ -80,7 +89,7 @@ Git index format 32-bit file size This is the on-disk size from stat(2), truncated to 32-bit. - 160-bit SHA-1 for the represented object + Object name for the represented object A 16-bit 'flags' field split into (high to low bits) @@ -134,14 +143,35 @@ Git index format == Extensions -=== Cached tree - - Cached tree extension contains pre-computed hashes for trees that can - be derived from the index. It helps speed up tree object generation - from index for a new commit. - - When a path is updated in index, the path must be invalidated and - removed from tree cache. +=== Cache tree + + Since the index does not record entries for directories, the cache + entries cannot describe tree objects that already exist in the object + database for regions of the index that are unchanged from an existing + commit. The cache tree extension stores a recursive tree structure that + describes the trees that already exist and completely match sections of + the cache entries. This speeds up tree object generation from the index + for a new commit by only computing the trees that are "new" to that + commit. It also assists when comparing the index to another tree, such + as `HEAD^{tree}`, since sections of the index can be skipped when a tree + comparison demonstrates equality. + + The recursive tree structure uses nodes that store a number of cache + entries, a list of subnodes, and an object ID (OID). The OID references + the existing tree for that node, if it is known to exist. The subnodes + correspond to subdirectories that themselves have cache tree nodes. The + number of cache entries corresponds to the number of cache entries in + the index that describe paths within that tree's directory. + + The extension tracks the full directory structure in the cache tree + extension, but this is generally smaller than the full cache entry list. + + When a path is updated in index, Git invalidates all nodes of the + recursive cache tree corresponding to the parent directories of that + path. We store these tree nodes as being "invalid" by using "-1" as the + number of cache entries. Invalid nodes still store a span of index + entries, allowing Git to focus its efforts when reconstructing a full + cache tree. The signature for this extension is { 'T', 'R', 'E', 'E' }. @@ -160,8 +190,8 @@ Git index format - A newline (ASCII 10); and - - 160-bit object name for the object that would result from writing - this span of index as a tree. + - Object name for the object that would result from writing this span + of index as a tree. An entry can be in an invalidated state and is represented by having a negative number in the entry_count field. In this case, there is no @@ -172,7 +202,8 @@ Git index format first entry represents the root level of the repository, followed by the first subtree--let's call this A--of the root level (with its name relative to the root level), followed by the first subtree of A (with - its name relative to A), ... + its name relative to A), and so on. The specified number of subtrees + indicates when the current level of the recursive stack is complete. === Resolve undo @@ -198,7 +229,7 @@ Git index format stage 1 to 3 (a missing stage is represented by "0" in this field); and - - At most three 160-bit object names of the entry in stages from 1 to 3 + - At most three object names of the entry in stages from 1 to 3 (nothing is written for a missing stage). === Split index @@ -211,8 +242,8 @@ Git index format The extension consists of: - - 160-bit SHA-1 of the shared index file. The shared index file path - is $GIT_DIR/sharedindex.<SHA-1>. If all 160 bits are zero, the + - Hash of the shared index file. The shared index file path + is $GIT_DIR/sharedindex.<hash>. If all bits are zero, the index does not require a shared index file. - An ewah-encoded delete bitmap, each bit represents an entry in the @@ -249,14 +280,14 @@ Git index format - Stat data of $GIT_DIR/info/exclude. See "Index entry" section from ctime field until "file size". - - Stat data of core.excludesfile + - Stat data of core.excludesFile - 32-bit dir_flags (see struct dir_struct) - - 160-bit SHA-1 of $GIT_DIR/info/exclude. Null SHA-1 means the file + - Hash of $GIT_DIR/info/exclude. A null hash means the file does not exist. - - 160-bit SHA-1 of core.excludesfile. Null SHA-1 means the file does + - Hash of core.excludesFile. A null hash means the file does not exist. - NUL-terminated string of per-dir exclude file name. This usually @@ -285,13 +316,13 @@ The remaining data of each directory block is grouped by type: - An ewah bitmap, the n-th bit records "check-only" bit of read_directory_recursive() for the n-th directory. - - An ewah bitmap, the n-th bit indicates whether SHA-1 and stat data + - An ewah bitmap, the n-th bit indicates whether hash and stat data is valid for the n-th directory and exists in the next data. - An array of stat data. The n-th data corresponds with the n-th "one" bit in the previous ewah bitmap. - - An array of SHA-1. The n-th SHA-1 corresponds with the n-th "one" bit + - An array of hashes. The n-th hash corresponds with the n-th "one" bit in the previous ewah bitmap. - One NUL. @@ -304,12 +335,18 @@ The remaining data of each directory block is grouped by type: The extension starts with - - 32-bit version number: the current supported version is 1. + - 32-bit version number: the current supported versions are 1 and 2. - - 64-bit time: the extension data reflects all changes through the given + - (Version 1) + 64-bit time: the extension data reflects all changes through the given time which is stored as the nanoseconds elapsed since midnight, January 1, 1970. + - (Version 2) + A null terminated string: an opaque token defined by the file system + monitor application. The extension data reflects all changes relative + to that token. + - 32-bit bitmap size: the size of the CE_FSMONITOR_VALID bitmap. - An ewah bitmap, the n-th bit indicates whether the n-th index entry @@ -318,7 +355,7 @@ The remaining data of each directory block is grouped by type: == End of Index Entry The End of Index Entry (EOIE) is used to locate the end of the variable - length index entries and the begining of the extensions. Code can take + length index entries and the beginning of the extensions. Code can take advantage of this to quickly locate the index extensions without having to parse through all of the index entries. @@ -330,12 +367,12 @@ The remaining data of each directory block is grouped by type: - 32-bit offset to the end of the index entries - - 160-bit SHA-1 over the extension types and their sizes (but not + - Hash over the extension types and their sizes (but not their contents). E.g. if we have "TREE" extension that is N-bytes long, "REUC" extension that is M-bytes long, followed by "EOIE", then the hash would be: - SHA-1("TREE" + <binary representation of N> + + Hash("TREE" + <binary representation of N> + "REUC" + <binary representation of M>) == Index Entry Offset Table @@ -351,7 +388,19 @@ The remaining data of each directory block is grouped by type: - A number of index offset entries each consisting of: - - 32-bit offset from the begining of the file to the first cache entry + - 32-bit offset from the beginning of the file to the first cache entry in this block of entries. - 32-bit count of cache entries in this block + +== Sparse Directory Entries + + When using sparse-checkout in cone mode, some entire directories within + the index can be summarized by pointing to a tree object instead of the + entire expanded list of paths within that tree. An index containing such + entries is a "sparse index". Index format versions 4 and less were not + implemented with such entries in mind. Thus, for these versions, an + index containing sparse directory entries will include this extension + with signature { 's', 'd', 'i', 'r' }. Like the split-index extension, + tools should avoid interacting with a sparse index unless they understand + this extension. diff --git a/Documentation/technical/multi-pack-index.txt b/Documentation/technical/multi-pack-index.txt index d7e57639f7..fb688976c4 100644 --- a/Documentation/technical/multi-pack-index.txt +++ b/Documentation/technical/multi-pack-index.txt @@ -36,15 +36,16 @@ Design Details directory of an alternate. It refers only to packfiles in that same directory. -- The pack.multiIndex config setting must be on to consume MIDX files. +- The core.multiPackIndex config setting must be on to consume MIDX files. - The file format includes parameters for the object ID hash function, so a future change of hash algorithm does not require a change in format. - The MIDX keeps only one record per object ID. If an object appears - in multiple packfiles, then the MIDX selects the copy in the most- - recently modified packfile. + in multiple packfiles, then the MIDX selects the copy in the + preferred packfile, otherwise selecting from the most-recently + modified packfile. - If there exist packfiles in the pack directory not registered in the MIDX, then those packfiles are loaded into the `packed_git` @@ -60,10 +61,6 @@ Design Details Future Work ----------- -- Add a 'verify' subcommand to the 'git midx' builtin to verify the - contents of the multi-pack-index file match the offsets listed in - the corresponding pack-indexes. - - The multi-pack-index allows many packfiles, especially in a context where repacking is expensive (such as a very large repo), or unexpected maintenance time is unacceptable (such as a high-demand @@ -102,8 +99,8 @@ Related Links [0] https://bugs.chromium.org/p/git/issues/detail?id=6 Chromium work item for: Multi-Pack Index (MIDX) -[1] https://public-inbox.org/git/20180107181459.222909-1-dstolee@microsoft.com/ +[1] https://lore.kernel.org/git/20180107181459.222909-1-dstolee@microsoft.com/ An earlier RFC for the multi-pack-index feature -[2] https://public-inbox.org/git/alpine.DEB.2.20.1803091557510.23109@alexmv-linux/ +[2] https://lore.kernel.org/git/alpine.DEB.2.20.1803091557510.23109@alexmv-linux/ Git Merge 2018 Contributor's summit notes (includes discussion of MIDX) diff --git a/Documentation/technical/pack-format.txt b/Documentation/technical/pack-format.txt index cab5bdd2ff..8d2f42f29e 100644 --- a/Documentation/technical/pack-format.txt +++ b/Documentation/technical/pack-format.txt @@ -1,6 +1,12 @@ Git pack format =============== +== Checksums and object IDs + +In a repository using the traditional SHA-1, pack checksums, index checksums, +and object IDs (object names) mentioned below are all computed using SHA-1. +Similarly, in SHA-256 repositories, these values are computed using SHA-256. + == pack-*.pack files have the following format: - A header appears at the beginning and consists of the following: @@ -26,7 +32,7 @@ Git pack format (deltified representation) n-byte type and length (3-bit type, (n-1)*7+4-bit length) - 20-byte base object name if OBJ_REF_DELTA or a negative relative + base object name if OBJ_REF_DELTA or a negative relative offset from the delta object's position in the pack if this is an OBJ_OFS_DELTA object compressed delta data @@ -34,7 +40,7 @@ Git pack format Observation: length of each object is encoded in a variable length format and is not constrained to 32-bit or anything. - - The trailer records 20-byte SHA-1 checksum of all of the above. + - The trailer records a pack checksum of all of the above. === Object types @@ -49,6 +55,18 @@ Valid object types are: Type 5 is reserved for future expansion. Type 0 is invalid. +=== Size encoding + +This document uses the following "size encoding" of non-negative +integers: From each byte, the seven least significant bits are +used to form the resulting integer. As long as the most significant +bit is 1, this process continues; the byte with MSB 0 provides the +last seven bits. The seven-bit chunks are concatenated. Later +values are more significant. + +This size encoding should not be confused with the "offset encoding", +which is also used in this document. + === Deltified representation Conceptually there are only four object types: commit, tree, tag and @@ -58,8 +76,8 @@ ofs-delta and ref-delta, which is only valid in a pack file. Both ofs-delta and ref-delta store the "delta" to be applied to another object (called 'base object') to reconstruct the object. The -difference between them is, ref-delta directly encodes 20-byte base -object name. If the base object is in the same pack, ofs-delta encodes +difference between them is, ref-delta directly encodes base object +name. If the base object is in the same pack, ofs-delta encodes the offset of the base object in the pack instead. The base object could also be deltified if it's in the same pack. @@ -67,7 +85,10 @@ Ref-delta can also refer to an object outside the pack (i.e. the so-called "thin pack"). When stored on disk however, the pack should be self contained to avoid cyclic dependency. -The delta data is a sequence of instructions to reconstruct an object +The delta data starts with the size of the base object and the +size of the object to be reconstructed. These sizes are +encoded using the size encoding from above. The remainder of +the delta data is a sequence of instructions to reconstruct the object from the base object. If the base object is deltified, it must be converted to canonical form first. Each instruction appends more and more data to the target object until it's complete. There are two @@ -143,14 +164,14 @@ This is the instruction reserved for future expansion. object is stored in the packfile as the offset from the beginning. - 20-byte object name. + one object name of the appropriate size. - The file is concluded with a trailer: - A copy of the 20-byte SHA-1 checksum at the end of - corresponding packfile. + A copy of the pack checksum at the end of the corresponding + packfile. - 20-byte SHA-1-checksum of all of the above. + Index checksum of all of the above. Pack Idx file: @@ -198,7 +219,7 @@ Pack file entry: <+ If it is not DELTA, then deflated bytes (the size above is the size before compression). If it is REF_DELTA, then - 20-byte base object name SHA-1 (the size above is the + base object name (the size above is the size of the delta data that follows). delta data, deflated. If it is OFS_DELTA, then @@ -227,9 +248,9 @@ Pack file entry: <+ - A 256-entry fan-out table just like v1. - - A table of sorted 20-byte SHA-1 object names. These are - packed together without offset values to reduce the cache - footprint of the binary search for a specific object name. + - A table of sorted object names. These are packed together + without offset values to reduce the cache footprint of the + binary search for a specific object name. - A table of 4-byte CRC32 values of the packed object data. This is new in v2 so compressed data can be copied directly @@ -248,10 +269,30 @@ Pack file entry: <+ - The same trailer as a v1 pack file: - A copy of the 20-byte SHA-1 checksum at the end of + A copy of the pack checksum at the end of corresponding packfile. - 20-byte SHA-1-checksum of all of the above. + Index checksum of all of the above. + +== pack-*.rev files have the format: + + - A 4-byte magic number '0x52494458' ('RIDX'). + + - A 4-byte version identifier (= 1). + + - A 4-byte hash function identifier (= 1 for SHA-1, 2 for SHA-256). + + - A table of index positions (one per packed object, num_objects in + total, each a 4-byte unsigned integer in network order), sorted by + their corresponding offsets in the packfile. + + - A trailer, containing a: + + checksum of the corresponding packfile, and + + a checksum of all of the above. + +All 4-byte numbers are in network order. == multi-pack-index (MIDX) files have the following format: @@ -273,7 +314,12 @@ HEADER: Git only writes or recognizes version 1. 1-byte Object Id Version - Git only writes or recognizes version 1 (SHA1). + We infer the length of object IDs (OIDs) from this value: + 1 => SHA-1 + 2 => SHA-256 + If the hash type does not match the repository's hash algorithm, + the multi-pack-index file should be ignored with a warning + presented to the user. 1-byte number of "chunks" @@ -290,6 +336,9 @@ CHUNK LOOKUP: (Chunks are provided in file-order, so you can infer the length using the next chunk position if necessary.) + The CHUNK LOOKUP matches the table of contents from + link:technical/chunk-format.html[the chunk-based file format]. + The remaining data in the body is described one chunk at a time, and these chunks may be given in any order. Chunks are required unless otherwise specified. @@ -315,10 +364,11 @@ CHUNK DATA: Stores two 4-byte values for every object. 1: The pack-int-id for the pack storing this object. 2: The offset within the pack. - If all offsets are less than 2^31, then the large offset chunk + If all offsets are less than 2^32, then the large offset chunk will not exist and offsets are stored as in IDX v1. If there is at least one offset value larger than 2^32-1, then - the large offset chunk must exist. If the large offset chunk + the large offset chunk must exist, and offsets larger than + 2^31-1 must be stored in it instead. If the large offset chunk exists and the 31st bit is on, then removing that bit reveals the row in the large offsets containing the 8-byte offset of this object. @@ -328,4 +378,87 @@ CHUNK DATA: TRAILER: - 20-byte SHA1-checksum of the above contents. + Index checksum of the above contents. + +== multi-pack-index reverse indexes + +Similar to the pack-based reverse index, the multi-pack index can also +be used to generate a reverse index. + +Instead of mapping between offset, pack-, and index position, this +reverse index maps between an object's position within the MIDX, and +that object's position within a pseudo-pack that the MIDX describes +(i.e., the ith entry of the multi-pack reverse index holds the MIDX +position of ith object in pseudo-pack order). + +To clarify the difference between these orderings, consider a multi-pack +reachability bitmap (which does not yet exist, but is what we are +building towards here). Each bit needs to correspond to an object in the +MIDX, and so we need an efficient mapping from bit position to MIDX +position. + +One solution is to let bits occupy the same position in the oid-sorted +index stored by the MIDX. But because oids are effectively random, their +resulting reachability bitmaps would have no locality, and thus compress +poorly. (This is the reason that single-pack bitmaps use the pack +ordering, and not the .idx ordering, for the same purpose.) + +So we'd like to define an ordering for the whole MIDX based around +pack ordering, which has far better locality (and thus compresses more +efficiently). We can think of a pseudo-pack created by the concatenation +of all of the packs in the MIDX. E.g., if we had a MIDX with three packs +(a, b, c), with 10, 15, and 20 objects respectively, we can imagine an +ordering of the objects like: + + |a,0|a,1|...|a,9|b,0|b,1|...|b,14|c,0|c,1|...|c,19| + +where the ordering of the packs is defined by the MIDX's pack list, +and then the ordering of objects within each pack is the same as the +order in the actual packfile. + +Given the list of packs and their counts of objects, you can +naïvely reconstruct that pseudo-pack ordering (e.g., the object at +position 27 must be (c,1) because packs "a" and "b" consumed 25 of the +slots). But there's a catch. Objects may be duplicated between packs, in +which case the MIDX only stores one pointer to the object (and thus we'd +want only one slot in the bitmap). + +Callers could handle duplicates themselves by reading objects in order +of their bit-position, but that's linear in the number of objects, and +much too expensive for ordinary bitmap lookups. Building a reverse index +solves this, since it is the logical inverse of the index, and that +index has already removed duplicates. But, building a reverse index on +the fly can be expensive. Since we already have an on-disk format for +pack-based reverse indexes, let's reuse it for the MIDX's pseudo-pack, +too. + +Objects from the MIDX are ordered as follows to string together the +pseudo-pack. Let `pack(o)` return the pack from which `o` was selected +by the MIDX, and define an ordering of packs based on their numeric ID +(as stored by the MIDX). Let `offset(o)` return the object offset of `o` +within `pack(o)`. Then, compare `o1` and `o2` as follows: + + - If one of `pack(o1)` and `pack(o2)` is preferred and the other + is not, then the preferred one sorts first. ++ +(This is a detail that allows the MIDX bitmap to determine which +pack should be used by the pack-reuse mechanism, since it can ask +the MIDX for the pack containing the object at bit position 0). + + - If `pack(o1) ≠pack(o2)`, then sort the two objects in descending + order based on the pack ID. + + - Otherwise, `pack(o1) = pack(o2)`, and the objects are sorted in + pack-order (i.e., `o1` sorts ahead of `o2` exactly when `offset(o1) + < offset(o2)`). + +In short, a MIDX's pseudo-pack is the de-duplicated concatenation of +objects in packs stored by the MIDX, laid out in pack order, and the +packs arranged in MIDX order (with the preferred pack coming first). + +Finally, note that the MIDX's reverse index is not stored as a chunk in +the multi-pack-index itself. This is done because the reverse index +includes the checksum of the pack or MIDX to which it belongs, which +makes it impossible to write in the MIDX. To avoid races when rewriting +the MIDX, a MIDX reverse index includes the MIDX's checksum in its +filename (e.g., `multi-pack-index-xyz.rev`). diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index c73e72de0e..e13a2c064d 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -96,7 +96,7 @@ Basically what the Git client is doing to connect to an 'upload-pack' process on the server side over the Git protocol is this: $ echo -e -n \ - "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" | + "003agit-upload-pack /schacon/gitbook.git\0host=example.com\0" | nc -v example.com 9418 @@ -171,9 +171,9 @@ with a version number (if "version=1" is sent as an Extra Parameter), and a listing of each reference it has (all branches and tags) along with the object name that each reference currently points to. - $ echo -e -n "0044git-upload-pack /schacon/gitbook.git\0host=example.com\0\0version=1\0" | + $ echo -e -n "0045git-upload-pack /schacon/gitbook.git\0host=example.com\0\0version=1\0" | nc -v example.com 9418 - 000aversion 1 + 000eversion 1 00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag 00441d3fcd5ced445d1abc402225c0b8a1299641f497 refs/heads/integration @@ -503,8 +503,8 @@ The reference discovery phase is done nearly the same way as it is in the fetching protocol. Each reference obj-id and name on the server is sent in packet-line format to the client, followed by a flush-pkt. The only real difference is that the capability listing is different - the only -possible values are 'report-status', 'delete-refs', 'ofs-delta' and -'push-options'. +possible values are 'report-status', 'report-status-v2', 'delete-refs', +'ofs-delta', 'atomic' and 'push-options'. Reference Update Request and Packfile Transfer ---------------------------------------------- @@ -625,7 +625,7 @@ Report Status ------------- After receiving the pack data from the sender, the receiver sends a -report if 'report-status' capability is in effect. +report if 'report-status' or 'report-status-v2' capability is in effect. It is a short listing of what happened in that update. It will first list the status of the packfile unpacking as either 'unpack ok' or 'unpack [error]'. Then it will list the status for each of the references @@ -644,7 +644,42 @@ update was successful, or 'ng [refname] [error]' if the update was not. command-ok = PKT-LINE("ok" SP refname) command-fail = PKT-LINE("ng" SP refname SP error-msg) - error-msg = 1*(OCTECT) ; where not "ok" + error-msg = 1*(OCTET) ; where not "ok" +---- + +The 'report-status-v2' capability extends the protocol by adding new option +lines in order to support reporting of reference rewritten by the +'proc-receive' hook. The 'proc-receive' hook may handle a command for a +pseudo-reference which may create or update one or more references, and each +reference may have different name, different new-oid, and different old-oid. + +---- + report-status-v2 = unpack-status + 1*(command-status-v2) + flush-pkt + + unpack-status = PKT-LINE("unpack" SP unpack-result) + unpack-result = "ok" / error-msg + + command-status-v2 = command-ok-v2 / command-fail + command-ok-v2 = command-ok + *option-line + + command-ok = PKT-LINE("ok" SP refname) + command-fail = PKT-LINE("ng" SP refname SP error-msg) + + error-msg = 1*(OCTET) ; where not "ok" + + option-line = *1(option-refname) + *1(option-old-oid) + *1(option-new-oid) + *1(option-forced-update) + + option-refname = PKT-LINE("option" SP "refname" SP refname) + option-old-oid = PKT-LINE("option" SP "old-oid" SP obj-id) + option-new-oid = PKT-LINE("option" SP "new-oid" SP obj-id) + option-force = PKT-LINE("option" SP "forced-update") + ---- Updates can be unsuccessful for a number of reasons. The reference can have diff --git a/Documentation/technical/packfile-uri.txt b/Documentation/technical/packfile-uri.txt new file mode 100644 index 0000000000..1eb525fe76 --- /dev/null +++ b/Documentation/technical/packfile-uri.txt @@ -0,0 +1,82 @@ +Packfile URIs +============= + +This feature allows servers to serve part of their packfile response as URIs. +This allows server designs that improve scalability in bandwidth and CPU usage +(for example, by serving some data through a CDN), and (in the future) provides +some measure of resumability to clients. + +This feature is available only in protocol version 2. + +Protocol +-------- + +The server advertises the `packfile-uris` capability. + +If the client then communicates which protocols (HTTPS, etc.) it supports with +a `packfile-uris` argument, the server MAY send a `packfile-uris` section +directly before the `packfile` section (right after `wanted-refs` if it is +sent) containing URIs of any of the given protocols. The URIs point to +packfiles that use only features that the client has declared that it supports +(e.g. ofs-delta and thin-pack). See protocol-v2.txt for the documentation of +this section. + +Clients should then download and index all the given URIs (in addition to +downloading and indexing the packfile given in the `packfile` section of the +response) before performing the connectivity check. + +Server design +------------- + +The server can be trivially made compatible with the proposed protocol by +having it advertise `packfile-uris`, tolerating the client sending +`packfile-uris`, and never sending any `packfile-uris` section. But we should +include some sort of non-trivial implementation in the Minimum Viable Product, +at least so that we can test the client. + +This is the implementation: a feature, marked experimental, that allows the +server to be configured by one or more `uploadpack.blobPackfileUri= +<object-hash> <pack-hash> <uri>` entries. Whenever the list of objects to be +sent is assembled, all such blobs are excluded, replaced with URIs. As noted +in "Future work" below, the server can evolve in the future to support +excluding other objects (or other implementations of servers could be made +that support excluding other objects) without needing a protocol change, so +clients should not expect that packfiles downloaded in this way only contain +single blobs. + +Client design +------------- + +The client has a config variable `fetch.uriprotocols` that determines which +protocols the end user is willing to use. By default, this is empty. + +When the client downloads the given URIs, it should store them with "keep" +files, just like it does with the packfile in the `packfile` section. These +additional "keep" files can only be removed after the refs have been updated - +just like the "keep" file for the packfile in the `packfile` section. + +The division of work (initial fetch + additional URIs) introduces convenient +points for resumption of an interrupted clone - such resumption can be done +after the Minimum Viable Product (see "Future work"). + +Future work +----------- + +The protocol design allows some evolution of the server and client without any +need for protocol changes, so only a small-scoped design is included here to +form the MVP. For example, the following can be done: + + * On the server, more sophisticated means of excluding objects (e.g. by + specifying a commit to represent that commit and all objects that it + references). + * On the client, resumption of clone. If a clone is interrupted, information + could be recorded in the repository's config and a "clone-resume" command + can resume the clone in progress. (Resumption of subsequent fetches is more + difficult because that must deal with the user wanting to use the repository + even after the fetch was interrupted.) + +There are some possible features that will require a change in protocol: + + * Additional HTTP headers (e.g. authentication) + * Byte range support + * Different file formats referenced by URIs (e.g. raw object) diff --git a/Documentation/technical/parallel-checkout.txt b/Documentation/technical/parallel-checkout.txt new file mode 100644 index 0000000000..e790258a1a --- /dev/null +++ b/Documentation/technical/parallel-checkout.txt @@ -0,0 +1,270 @@ +Parallel Checkout Design Notes +============================== + +The "Parallel Checkout" feature attempts to use multiple processes to +parallelize the work of uncompressing the blobs, applying in-core +filters, and writing the resulting contents to the working tree during a +checkout operation. It can be used by all checkout-related commands, +such as `clone`, `checkout`, `reset`, `sparse-checkout`, and others. + +These commands share the following basic structure: + +* Step 1: Read the current index file into memory. + +* Step 2: Modify the in-memory index based upon the command, and + temporarily mark all cache entries that need to be updated. + +* Step 3: Populate the working tree to match the new candidate index. + This includes iterating over all of the to-be-updated cache entries + and delete, create, or overwrite the associated files in the working + tree. + +* Step 4: Write the new index to disk. + +Step 3 is the focus of the "parallel checkout" effort described here. + +Sequential Implementation +------------------------- + +For the purposes of discussion here, the current sequential +implementation of Step 3 is divided in 3 parts, each one implemented in +its own function: + +* Step 3a: `unpack-trees.c:check_updates()` contains a series of + sequential loops iterating over the `cache_entry`'s array. The main + loop in this function calls the Step 3b function for each of the + to-be-updated entries. + +* Step 3b: `entry.c:checkout_entry()` examines the existing working tree + for file conflicts, collisions, and unsaved changes. It removes files + and creates leading directories as necessary. It calls the Step 3c + function for each entry to be written. + +* Step 3c: `entry.c:write_entry()` loads the blob into memory, smudges + it if necessary, creates the file in the working tree, writes the + smudged contents, calls `fstat()` or `lstat()`, and updates the + associated `cache_entry` struct with the stat information gathered. + +It wouldn't be safe to perform Step 3b in parallel, as there could be +race conditions between file creations and removals. Instead, the +parallel checkout framework lets the sequential code handle Step 3b, +and uses parallel workers to replace the sequential +`entry.c:write_entry()` calls from Step 3c. + +Rejected Multi-Threaded Solution +-------------------------------- + +The most "straightforward" implementation would be to spread the set of +to-be-updated cache entries across multiple threads. But due to the +thread-unsafe functions in the ODB code, we would have to use locks to +coordinate the parallel operation. An early prototype of this solution +showed that the multi-threaded checkout would bring performance +improvements over the sequential code, but there was still too much lock +contention. A `perf` profiling indicated that around 20% of the runtime +during a local Linux clone (on an SSD) was spent in locking functions. +For this reason this approach was rejected in favor of using multiple +child processes, which led to a better performance. + +Multi-Process Solution +---------------------- + +Parallel checkout alters the aforementioned Step 3 to use multiple +`checkout--worker` background processes to distribute the work. The +long-running worker processes are controlled by the foreground Git +command using the existing run-command API. + +Overview +~~~~~~~~ + +Step 3b is only slightly altered; for each entry to be checked out, the +main process performs the following steps: + +* M1: Check whether there is any untracked or unclean file in the + working tree which would be overwritten by this entry, and decide + whether to proceed (removing the file(s)) or not. + +* M2: Create the leading directories. + +* M3: Load the conversion attributes for the entry's path. + +* M4: Check, based on the entry's type and conversion attributes, + whether the entry is eligible for parallel checkout (more on this + later). If it is eligible, enqueue the entry and the loaded + attributes to later write the entry in parallel. If not, write the + entry right away, using the default sequential code. + +Note: we save the conversion attributes associated with each entry +because the workers don't have access to the main process' index state, +so they can't load the attributes by themselves (and the attributes are +needed to properly smudge the entry). Additionally, this has a positive +impact on performance as (1) we don't need to load the attributes twice +and (2) the attributes machinery is optimized to handle paths in +sequential order. + +After all entries have passed through the above steps, the main process +checks if the number of enqueued entries is sufficient to spread among +the workers. If not, it just writes them sequentially. Otherwise, it +spawns the workers and distributes the queued entries uniformly in +continuous chunks. This aims to minimize the chances of two workers +writing to the same directory simultaneously, which could increase lock +contention in the kernel. + +Then, for each assigned item, each worker: + +* W1: Checks if there is any non-directory file in the leading part of + the entry's path or if there already exists a file at the entry' path. + If so, mark the entry with `PC_ITEM_COLLIDED` and skip it (more on + this later). + +* W2: Creates the file (with O_CREAT and O_EXCL). + +* W3: Loads the blob into memory (inflating and delta reconstructing + it). + +* W4: Applies any required in-process filter, like end-of-line + conversion and re-encoding. + +* W5: Writes the result to the file descriptor opened at W2. + +* W6: Calls `fstat()` or lstat()` on the just-written path, and sends + the result back to the main process, together with the end status of + the operation and the item's identification number. + +Note that, when possible, steps W3 to W5 are delegated to the streaming +machinery, removing the need to keep the entire blob in memory. + +If the worker fails to read the blob or to write it to the working tree, +it removes the created file to avoid leaving empty files behind. This is +the *only* time a worker is allowed to remove a file. + +As mentioned earlier, it is the responsibility of the main process to +remove any file that blocks the checkout operation (or abort if the +removal(s) would cause data loss and the user didn't ask to `--force`). +This is crucial to avoid race conditions and also to properly detect +path collisions at Step W1. + +After the workers finish writing the items and sending back the required +information, the main process handles the results in two steps: + +- First, it updates the in-memory index with the `lstat()` information + sent by the workers. (This must be done first as this information + might me required in the following step.) + +- Then it writes the items which collided on disk (i.e. items marked + with `PC_ITEM_COLLIDED`). More on this below. + +Path Collisions +--------------- + +Path collisions happen when two different paths correspond to the same +entry in the file system. E.g. the paths 'a' and 'A' would collide in a +case-insensitive file system. + +The sequential checkout deals with collisions in the same way that it +deals with files that were already present in the working tree before +checkout. Basically, it checks if the path that it wants to write +already exists on disk, makes sure the existing file doesn't have +unsaved data, and then overwrites it. (To be more pedantic: it deletes +the existing file and creates the new one.) So, if there are multiple +colliding files to be checked out, the sequential code will write each +one of them but only the last will actually survive on disk. + +Parallel checkout aims to reproduce the same behavior. However, we +cannot let the workers racily write to the same file on disk. Instead, +the workers detect when the entry that they want to check out would +collide with an existing file, and mark it with `PC_ITEM_COLLIDED`. +Later, the main process can sequentially feed these entries back to +`checkout_entry()` without the risk of race conditions. On clone, this +also has the effect of marking the colliding entries to later emit a +warning for the user, like the classic sequential checkout does. + +The workers are able to detect both collisions among the entries being +concurrently written and collisions between a parallel-eligible entry +and an ineligible entry. The general idea for collision detection is +quite straightforward: for each parallel-eligible entry, the main +process must remove all files that prevent this entry from being written +(before enqueueing it). This includes any non-directory file in the +leading path of the entry. Later, when a worker gets assigned the entry, +it looks again for the non-directories files and for an already existing +file at the entry's path. If any of these checks finds something, the +worker knows that there was a path collision. + +Because parallel checkout can distinguish path collisions from the case +where the file was already present in the working tree before checkout, +we could alternatively choose to skip the checkout of colliding entries. +However, each entry that doesn't get written would have NULL `lstat()` +fields on the index. This could cause performance penalties for +subsequent commands that need to refresh the index, as they would have +to go to the file system to see if the entry is dirty. Thus, if we have +N entries in a colliding group and we decide to write and `lstat()` only +one of them, every subsequent `git-status` will have to read, convert, +and hash the written file N - 1 times. By checking out all colliding +entries (like the sequential code does), we only pay the overhead once, +during checkout. + +Eligible Entries for Parallel Checkout +-------------------------------------- + +As previously mentioned, not all entries passed to `checkout_entry()` +will be considered eligible for parallel checkout. More specifically, we +exclude: + +- Symbolic links; to avoid race conditions that, in combination with + path collisions, could cause workers to write files at the wrong + place. For example, if we were to concurrently check out a symlink + 'a' -> 'b' and a regular file 'A/f' in a case-insensitive file system, + we could potentially end up writing the file 'A/f' at 'a/f', due to a + race condition. + +- Regular files that require external filters (either "one shot" filters + or long-running process filters). These filters are black-boxes to Git + and may have their own internal locking or non-concurrent assumptions. + So it might not be safe to run multiple instances in parallel. ++ +Besides, long-running filters may use the delayed checkout feature to +postpone the return of some filtered blobs. The delayed checkout queue +and the parallel checkout queue are not compatible and should remain +separate. ++ +Note: regular files that only require internal filters, like end-of-line +conversion and re-encoding, are eligible for parallel checkout. + +Ineligible entries are checked out by the classic sequential codepath +*before* spawning workers. + +Note: submodules's files are also eligible for parallel checkout (as +long as they don't fall into any of the excluding categories mentioned +above). But since each submodule is checked out in its own child +process, we don't mix the superproject's and the submodules' files in +the same parallel checkout process or queue. + +The API +------- + +The parallel checkout API was designed with the goal of minimizing +changes to the current users of the checkout machinery. This means that +they don't have to call a different function for sequential or parallel +checkout. As already mentioned, `checkout_entry()` will automatically +insert the given entry in the parallel checkout queue when this feature +is enabled and the entry is eligible; otherwise, it will just write the +entry right away, using the sequential code. In general, callers of the +parallel checkout API should look similar to this: + +---------------------------------------------- +int pc_workers, pc_threshold, err = 0; +struct checkout state; + +get_parallel_checkout_configs(&pc_workers, &pc_threshold); + +/* + * This check is not strictly required, but it + * should save some time in sequential mode. + */ +if (pc_workers > 1) + init_parallel_checkout(); + +for (each cache_entry ce to-be-updated) + err |= checkout_entry(ce, &state, NULL, NULL); + +err |= run_parallel_checkout(&state, pc_workers, pc_threshold, NULL, NULL); +---------------------------------------------- diff --git a/Documentation/technical/partial-clone.txt b/Documentation/technical/partial-clone.txt index 896c7b3878..a0dd7c66f2 100644 --- a/Documentation/technical/partial-clone.txt +++ b/Documentation/technical/partial-clone.txt @@ -30,12 +30,20 @@ advance* during clone and fetch operations and thereby reduce download times and disk usage. Missing objects can later be "demand fetched" if/when needed. +A remote that can later provide the missing objects is called a +promisor remote, as it promises to send the objects when +requested. Initially Git supported only one promisor remote, the origin +remote from which the user cloned and that was configured in the +"extensions.partialClone" config option. Later support for more than +one promisor remote has been implemented. + Use of partial clone requires that the user be online and the origin -remote be available for on-demand fetching of missing objects. This may -or may not be problematic for the user. For example, if the user can -stay within the pre-selected subset of the source tree, they may not -encounter any missing objects. Alternatively, the user could try to -pre-fetch various objects if they know that they are going offline. +remote or other promisor remotes be available for on-demand fetching +of missing objects. This may or may not be problematic for the user. +For example, if the user can stay within the pre-selected subset of +the source tree, they may not encounter any missing objects. +Alternatively, the user could try to pre-fetch various objects if they +know that they are going offline. Non-Goals @@ -100,18 +108,18 @@ or commits that reference missing trees. Handling Missing Objects ------------------------ -- An object may be missing due to a partial clone or fetch, or missing due - to repository corruption. To differentiate these cases, the local - repository specially indicates such filtered packfiles obtained from the - promisor remote as "promisor packfiles". +- An object may be missing due to a partial clone or fetch, or missing + due to repository corruption. To differentiate these cases, the + local repository specially indicates such filtered packfiles + obtained from promisor remotes as "promisor packfiles". + These promisor packfiles consist of a "<name>.promisor" file with arbitrary contents (like the "<name>.keep" files), in addition to their "<name>.pack" and "<name>.idx" files. - The local repository considers a "promisor object" to be an object that - it knows (to the best of its ability) that the promisor remote has promised - that it has, either because the local repository has that object in one of + it knows (to the best of its ability) that promisor remotes have promised + that they have, 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 is a promisor object @@ -123,12 +131,12 @@ expensive-to-modify list of missing objects.[a] - Since almost all Git code currently expects any referenced object to be present locally and because we do not want to force every command to do a dry-run first, a fallback mechanism is added to allow Git to attempt - to dynamically fetch missing objects from the promisor remote. + to dynamically fetch missing objects from promisor remotes. + When the normal object lookup fails to find an object, Git invokes -fetch-object to try to get the object from the server and then retry -the object lookup. This allows objects to be "faulted in" without -complicated prediction algorithms. +promisor_remote_get_direct() to try to get the object from a promisor +remote and then retry the object lookup. This allows objects to be +"faulted in" without complicated prediction algorithms. + For efficiency reasons, no check as to whether the missing object is actually a promisor object is performed. @@ -157,51 +165,84 @@ and prefetch those objects in bulk. + We are not happy with this global variable and would like to remove it, but that requires significant refactoring of the object code to pass an -additional flag. We hope that concurrent efforts to add an ODB API can -encompass this. +additional flag. Fetching Missing Objects ------------------------ -- Fetching of objects is done using the existing transport mechanism using - transport_fetch_refs(), setting a new transport option - TRANS_OPT_NO_DEPENDENTS to indicate that only the objects themselves are - desired, not any object that they refer to. -+ -Because some transports invoke fetch_pack() in the same process, fetch_pack() -has been updated to not use any object flags when the corresponding argument -(no_dependents) is set. +- Fetching of objects is done by invoking a "git fetch" subprocess. - The local repository sends a request with the hashes of all requested - objects as "want" lines, and does not perform any packfile negotiation. + objects, and does not perform any packfile negotiation. It then receives a packfile. -- Because we are reusing the existing fetch-pack mechanism, fetching +- Because we are reusing the existing fetch mechanism, fetching currently fetches all objects referred to by the requested objects, even though they are not necessary. +Using many promisor remotes +--------------------------- + +Many promisor remotes can be configured and used. + +This allows for example a user to have multiple geographically-close +cache servers for fetching missing blobs while continuing to do +filtered `git-fetch` commands from the central server. + +When fetching objects, promisor remotes are tried one after the other +until all the objects have been fetched. + +Remotes that are considered "promisor" remotes are those specified by +the following configuration variables: + +- `extensions.partialClone = <name>` + +- `remote.<name>.promisor = true` + +- `remote.<name>.partialCloneFilter = ...` + +Only one promisor remote can be configured using the +`extensions.partialClone` config variable. This promisor remote will +be the last one tried when fetching objects. + +We decided to make it the last one we try, because it is likely that +someone using many promisor remotes is doing so because the other +promisor remotes are better for some reason (maybe they are closer or +faster for some kind of objects) than the origin, and the origin is +likely to be the remote specified by extensions.partialClone. + +This justification is not very strong, but one choice had to be made, +and anyway the long term plan should be to make the order somehow +fully configurable. + +For now though the other promisor remotes will be tried in the order +they appear in the config file. + Current Limitations ------------------- -- The remote used for a partial clone (or the first partial fetch - following a regular clone) is marked as the "promisor remote". +- It is not possible to specify the order in which the promisor + remotes are tried in other ways than the order in which they appear + in the config file. + -We are currently limited to a single promisor remote and only that -remote may be used for subsequent partial fetches. +It is also not possible to specify an order to be used when fetching +from one remote and a different order when fetching from another +remote. + +- It is not possible to push only specific objects to a promisor + remote. + -We accept this limitation because we believe initial users of this -feature will be using it on repositories with a strong single central -server. +It is not possible to push at the same time to multiple promisor +remote in a specific order. -- Dynamic object fetching will only ask the promisor remote for missing - objects. We assume that the promisor remote has a complete view of the +- Dynamic object fetching will only ask promisor remotes for missing + objects. We assume that promisor remotes have a complete view of the repository and can satisfy all such requests. - Repack essentially treats promisor and non-promisor packfiles as 2 - distinct partitions and does not mix them. Repack currently only works - on non-promisor packfiles and loose objects. + distinct partitions and does not mix them. - Dynamic object fetching invokes fetch-pack once *for each item* because most algorithms stumble upon a missing object and need to have @@ -218,20 +259,19 @@ server. Future Work ----------- -- Allow more than one promisor remote and define a strategy for fetching - missing objects from specific promisor remotes or of iterating over the - set of promisor remotes until a missing object is found. +- Improve the way to specify the order in which promisor remotes are + tried. + -A user might want to have multiple geographically-close cache servers -for fetching missing blobs while continuing to do filtered `git-fetch` -commands from the central server, for example. +For example this could allow to specify explicitly something like: +"When fetching from this remote, I want to use these promisor remotes +in this order, though, when pushing or fetching to that remote, I want +to use those promisor remotes in that order." + +- Allow pushing to promisor remotes. + -Or the user might want to work in a triangular work flow with multiple +The user might want to work in a triangular work flow with multiple promisor remotes that each have an incomplete view of the repository. -- Allow repack to work on promisor packfiles (while keeping them distinct - from non-promisor packfiles). - - Allow non-pathname-based filters to make use of packfile bitmaps (when present). This was just an omission during the initial implementation. @@ -299,26 +339,26 @@ Related Links [0] https://crbug.com/git/2 Bug#2: Partial Clone -[1] https://public-inbox.org/git/20170113155253.1644-1-benpeart@microsoft.com/ + +[1] https://lore.kernel.org/git/20170113155253.1644-1-benpeart@microsoft.com/ + Subject: [RFC] Add support for downloading blobs on demand + Date: Fri, 13 Jan 2017 10:52:53 -0500 -[2] https://public-inbox.org/git/cover.1506714999.git.jonathantanmy@google.com/ + +[2] https://lore.kernel.org/git/cover.1506714999.git.jonathantanmy@google.com/ + Subject: [PATCH 00/18] Partial clone (from clone to lazy fetch in 18 patches) + Date: Fri, 29 Sep 2017 13:11:36 -0700 -[3] https://public-inbox.org/git/20170426221346.25337-1-jonathantanmy@google.com/ + +[3] https://lore.kernel.org/git/20170426221346.25337-1-jonathantanmy@google.com/ + Subject: Proposal for missing blob support in Git repos + Date: Wed, 26 Apr 2017 15:13:46 -0700 -[4] https://public-inbox.org/git/1488999039-37631-1-git-send-email-git@jeffhostetler.com/ + +[4] https://lore.kernel.org/git/1488999039-37631-1-git-send-email-git@jeffhostetler.com/ + Subject: [PATCH 00/10] RFC Partial Clone and Fetch + Date: Wed, 8 Mar 2017 18:50:29 +0000 -[5] https://public-inbox.org/git/20170505152802.6724-1-benpeart@microsoft.com/ + +[5] https://lore.kernel.org/git/20170505152802.6724-1-benpeart@microsoft.com/ + Subject: [PATCH v7 00/10] refactor the filter process code into a reusable module + Date: Fri, 5 May 2017 11:27:52 -0400 -[6] https://public-inbox.org/git/20170714132651.170708-1-benpeart@microsoft.com/ + +[6] https://lore.kernel.org/git/20170714132651.170708-1-benpeart@microsoft.com/ + Subject: [RFC/PATCH v2 0/1] Add support for downloading blobs on demand + Date: Fri, 14 Jul 2017 09:26:50 -0400 diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt index 2b267c0da6..9dfade930d 100644 --- a/Documentation/technical/protocol-capabilities.txt +++ b/Documentation/technical/protocol-capabilities.txt @@ -22,13 +22,13 @@ was sent. Server MUST NOT ignore capabilities that client requested and server advertised. As a consequence of these rules, server MUST NOT advertise capabilities it does not understand. -The 'atomic', 'report-status', 'delete-refs', 'quiet', and 'push-cert' -capabilities are sent and recognized by the receive-pack (push to server) -process. +The 'atomic', 'report-status', 'report-status-v2', 'delete-refs', 'quiet', +and 'push-cert' capabilities are sent and recognized by the receive-pack +(push to server) process. The 'ofs-delta' and 'side-band-64k' capabilities are sent and recognized -by both upload-pack and receive-pack protocols. The 'agent' capability -may optionally be sent in both protocols. +by both upload-pack and receive-pack protocols. The 'agent' and 'session-id' +capabilities may optionally be sent in both protocols. All other capabilities are only recognized by the upload-pack (fetch from server) process. @@ -176,6 +176,21 @@ agent strings are purely informative for statistics and debugging purposes, and MUST NOT be used to programmatically assume the presence or absence of particular features. +object-format +------------- + +This capability, which takes a hash algorithm as an argument, indicates +that the server supports the given hash algorithms. It may be sent +multiple times; if so, the first one given is the one used in the ref +advertisement. + +When provided by the client, this indicates that it intends to use the +given hash algorithm to communicate. The algorithm provided must be one +that the server supports. + +If this capability is not provided, it is assumed that the only +supported algorithm is SHA-1. + symref ------ @@ -269,6 +284,17 @@ each reference was updated successfully. If any of those were not successful, it will send back an error message. See pack-protocol.txt for example messages. +report-status-v2 +---------------- + +Capability 'report-status-v2' extends capability 'report-status' by +adding new "option" directives in order to support reference rewritten by +the "proc-receive" hook. The "proc-receive" hook may handle a command +for a pseudo-reference which may create or update a reference with +different name, new-oid, and old-oid. While the capability +'report-status' cannot report for such case. See pack-protocol.txt +for details. + delete-refs ----------- @@ -309,15 +335,19 @@ allow-tip-sha1-in-want ---------------------- If the upload-pack server advertises this capability, fetch-pack may -send "want" lines with SHA-1s that exist at the server but are not -advertised by upload-pack. +send "want" lines with object names that exist at the server but are not +advertised by upload-pack. For historical reasons, the name of this +capability contains "sha1". Object names are always given using the +object format negotiated through the 'object-format' capability. allow-reachable-sha1-in-want ---------------------------- If the upload-pack server advertises this capability, fetch-pack may -send "want" lines with SHA-1s that exist at the server but are not -advertised by upload-pack. +send "want" lines with object names that exist at the server but are not +advertised by upload-pack. For historical reasons, the name of this +capability contains "sha1". Object names are always given using the +object format negotiated through the 'object-format' capability. push-cert=<nonce> ----------------- @@ -335,3 +365,16 @@ If the upload-pack server advertises the 'filter' capability, fetch-pack may send "filter" commands to request a partial clone or partial fetch and request that the server omit various objects from the packfile. + +session-id=<session id> +----------------------- + +The server may advertise a session ID that can be used to identify this process +across multiple requests. The client may advertise its own session ID back to +the server as well. + +Session IDs should be unique to a given process. They must fit within a +packet-line, and must not contain non-printable or whitespace characters. The +current implementation uses trace2 session IDs (see +link:api-trace2.html[api-trace2] for details), but this may change and users of +the session ID should not rely on this fact. diff --git a/Documentation/technical/protocol-v2.txt b/Documentation/technical/protocol-v2.txt index 03264c7d9a..1040d85319 100644 --- a/Documentation/technical/protocol-v2.txt +++ b/Documentation/technical/protocol-v2.txt @@ -33,6 +33,8 @@ In protocol v2 these special packets will have the following semantics: * '0000' Flush Packet (flush-pkt) - indicates the end of a message * '0001' Delimiter Packet (delim-pkt) - separates sections of a message + * '0002' Response End Packet (response-end-pkt) - indicates the end of a + response for stateless connections Initial Client Request ---------------------- @@ -141,7 +143,7 @@ Capabilities ------------ There are two different types of capabilities: normal capabilities, -which can be used to to convey information or alter the behavior of a +which can be used to convey information or alter the behavior of a request, and commands, which are the core actions that a client wants to perform (fetch, push, etc). @@ -190,11 +192,20 @@ ls-refs takes in the following arguments: When specified, only references having a prefix matching one of the provided prefixes are displayed. +If the 'unborn' feature is advertised the following argument can be +included in the client's request. + + unborn + The server will send information about HEAD even if it is a symref + pointing to an unborn branch in the form "unborn HEAD + symref-target:<target>". + The output of ls-refs is as follows: output = *ref flush-pkt - ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF) + obj-id-or-unborn = (obj-id | "unborn") + ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF) ref-attribute = (symref | peeled) symref = "symref-target:" symref-target peeled = "peeled:" obj-id @@ -252,7 +263,7 @@ A `fetch` request can take the following arguments: ofs-delta Indicate that the client understands PACKv2 with delta referring to its base by position in pack rather than by an oid. That is, - they can read OBJ_OFS_DELTA (ake type 6) in a packfile. + they can read OBJ_OFS_DELTA (aka type 6) in a packfile. If the 'shallow' feature is advertised the following arguments can be included in the clients request as well as the potential addition of the @@ -323,13 +334,34 @@ included in the client's request: 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. +If the 'packfile-uris' feature is advertised, the following argument +can be included in the client's request as well as the potential +addition of the 'packfile-uris' section in the server's response as +explained below. + + packfile-uris <comma-separated list of protocols> + Indicates to the server that the client is willing to receive + URIs of any of the given protocols in place of objects in the + sent packfile. Before performing the connectivity check, the + client should download from all given URIs. Currently, the + protocols supported are "http" and "https". + +If the 'wait-for-done' feature is advertised, the following argument +can be included in the client's request. + + wait-for-done + Indicates to the server that it should never send "ready", but + should wait for the client to say "done" before sending the + packfile. + The response of `fetch` is broken into a number of sections separated by delimiter packets (0001), with each section beginning with its section -header. +header. Most sections are sent only when the packfile is sent. - output = *section - section = (acknowledgments | shallow-info | wanted-refs | packfile) - (flush-pkt | delim-pkt) + output = acknowledgements flush-pkt | + [acknowledgments delim-pkt] [shallow-info delim-pkt] + [wanted-refs delim-pkt] [packfile-uris delim-pkt] + packfile flush-pkt acknowledgments = PKT-LINE("acknowledgments" LF) (nak | *ack) @@ -347,13 +379,17 @@ header. *PKT-LINE(wanted-ref LF) wanted-ref = obj-id SP refname + packfile-uris = PKT-LINE("packfile-uris" LF) *packfile-uri + packfile-uri = PKT-LINE(40*(HEXDIGIT) SP *%x20-ff LF) + packfile = PKT-LINE("packfile" LF) *PKT-LINE(%x01-03 *%x00-ff) acknowledgments section - * If the client determines that it is finished with negotiations - by sending a "done" line, the acknowledgments sections MUST be - omitted from the server's response. + * If the client determines that it is finished with negotiations by + sending a "done" line (thus requiring the server to send a packfile), + the acknowledgments sections MUST be omitted from the server's + response. * Always begins with the section header "acknowledgments" @@ -404,9 +440,6 @@ header. which the client has not indicated was shallow as a part of its request. - * This section is only included if a packfile section is also - included in the response. - wanted-refs section * This section is only included if the client has requested a ref using a 'want-ref' line and if a packfile section is also @@ -420,6 +453,20 @@ header. * The server MUST NOT send any refs which were not requested using 'want-ref' lines. + packfile-uris section + * This section is only included if the client sent + 'packfile-uris' and the server has at least one such URI to + send. + + * Always begins with the section header "packfile-uris". + + * For each URI the server sends, it sends a hash of the pack's + contents (as output by git index-pack) followed by the URI. + + * The hashes are 40 hex characters long. When Git upgrades to a new + hash algorithm, this might need to be updated. (It should match + whatever index-pack outputs after "pack\t" or "keep\t". + packfile section * This section is only included if the client has sent 'want' lines in its request and either requested that no more @@ -453,3 +500,56 @@ included in a request. This is done by sending each option as a a request. The provided options must not contain a NUL or LF character. + + object-format +~~~~~~~~~~~~~~~ + +The server can advertise the `object-format` capability with a value `X` (in the +form `object-format=X`) to notify the client that the server is able to deal +with objects using hash algorithm X. If not specified, the server is assumed to +only handle SHA-1. If the client would like to use a hash algorithm other than +SHA-1, it should specify its object-format string. + +session-id=<session id> +~~~~~~~~~~~~~~~~~~~~~~~ + +The server may advertise a session ID that can be used to identify this process +across multiple requests. The client may advertise its own session ID back to +the server as well. + +Session IDs should be unique to a given process. They must fit within a +packet-line, and must not contain non-printable or whitespace characters. The +current implementation uses trace2 session IDs (see +link:api-trace2.html[api-trace2] for details), but this may change and users of +the session ID should not rely on this fact. + +object-info +~~~~~~~~~~~ + +`object-info` is the command to retrieve information about one or more objects. +Its main purpose is to allow a client to make decisions based on this +information without having to fully fetch objects. Object size is the only +information that is currently supported. + +An `object-info` request takes the following arguments: + + size + Requests size information to be returned for each listed object id. + + oid <oid> + Indicates to the server an object which the client wants to obtain + information for. + +The response of `object-info` is a list of the requested object ids +and associated requested information, each separated by a single space. + + output = info flush-pkt + + info = PKT-LINE(attrs) LF) + *PKT-LINE(obj-info LF) + + attrs = attr | attrs SP attrs + + attr = "size" + + obj-info = obj-id SP obj-size diff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.txt index 4a8be4d144..ceda4bbfda 100644 --- a/Documentation/technical/racy-git.txt +++ b/Documentation/technical/racy-git.txt @@ -51,7 +51,7 @@ of git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git only fixes the issue for file systems with exactly 1 ns or 1 s resolution. Other file systems are still broken in current Linux kernels (e.g. CEPH, CIFS, NTFS, UDF), see -https://lkml.org/lkml/2015/6/9/714 +https://lore.kernel.org/lkml/5577240D.7020309@gmail.com/ Racy Git -------- diff --git a/Documentation/technical/reftable.txt b/Documentation/technical/reftable.txt new file mode 100644 index 0000000000..d7c3b645cf --- /dev/null +++ b/Documentation/technical/reftable.txt @@ -0,0 +1,1098 @@ +reftable +-------- + +Overview +~~~~~~~~ + +Problem statement +^^^^^^^^^^^^^^^^^ + +Some repositories contain a lot of references (e.g. android at 866k, +rails at 31k). The existing packed-refs format takes up a lot of space +(e.g. 62M), and does not scale with additional references. Lookup of a +single reference requires linearly scanning the file. + +Atomic pushes modifying multiple references require copying the entire +packed-refs file, which can be a considerable amount of data moved +(e.g. 62M in, 62M out) for even small transactions (2 refs modified). + +Repositories with many loose references occupy a large number of disk +blocks from the local file system, as each reference is its own file +storing 41 bytes (and another file for the corresponding reflog). This +negatively affects the number of inodes available when a large number of +repositories are stored on the same filesystem. Readers can be penalized +due to the larger number of syscalls required to traverse and read the +`$GIT_DIR/refs` directory. + + +Objectives +^^^^^^^^^^ + +* Near constant time lookup for any single reference, even when the +repository is cold and not in process or kernel cache. +* Near constant time verification if an object name is referred to by at least +one reference (for allow-tip-sha1-in-want). +* Efficient enumeration of an entire namespace, such as `refs/tags/`. +* Support atomic push with `O(size_of_update)` operations. +* Combine reflog storage with ref storage for small transactions. +* Separate reflog storage for base refs and historical logs. + +Description +^^^^^^^^^^^ + +A reftable file is a portable binary file format customized for +reference storage. References are sorted, enabling linear scans, binary +search lookup, and range scans. + +Storage in the file is organized into variable sized blocks. Prefix +compression is used within a single block to reduce disk space. Block +size and alignment is tunable by the writer. + +Performance +^^^^^^^^^^^ + +Space used, packed-refs vs. reftable: + +[cols=",>,>,>,>,>",options="header",] +|=============================================================== +|repository |packed-refs |reftable |% original |avg ref |avg obj +|android |62.2 M |36.1 M |58.0% |33 bytes |5 bytes +|rails |1.8 M |1.1 M |57.7% |29 bytes |4 bytes +|git |78.7 K |48.1 K |61.0% |50 bytes |4 bytes +|git (heads) |332 b |269 b |81.0% |33 bytes |0 bytes +|=============================================================== + +Scan (read 866k refs), by reference name lookup (single ref from 866k +refs), and by SHA-1 lookup (refs with that SHA-1, from 866k refs): + +[cols=",>,>,>,>",options="header",] +|========================================================= +|format |cache |scan |by name |by SHA-1 +|packed-refs |cold |402 ms |409,660.1 usec |412,535.8 usec +|packed-refs |hot | |6,844.6 usec |20,110.1 usec +|reftable |cold |112 ms |33.9 usec |323.2 usec +|reftable |hot | |20.2 usec |320.8 usec +|========================================================= + +Space used for 149,932 log entries for 43,061 refs, reflog vs. reftable: + +[cols=",>,>",options="header",] +|================================ +|format |size |avg entry +|$GIT_DIR/logs |173 M |1209 bytes +|reftable |5 M |37 bytes +|================================ + +Details +~~~~~~~ + +Peeling +^^^^^^^ + +References stored in a reftable are peeled, a record for an annotated +(or signed) tag records both the tag object, and the object it refers +to. This is analogous to storage in the packed-refs format. + +Reference name encoding +^^^^^^^^^^^^^^^^^^^^^^^ + +Reference names are an uninterpreted sequence of bytes that must pass +linkgit:git-check-ref-format[1] as a valid reference name. + +Key unicity +^^^^^^^^^^^ + +Each entry must have a unique key; repeated keys are disallowed. + +Network byte order +^^^^^^^^^^^^^^^^^^ + +All multi-byte, fixed width fields are in network byte order. + +Varint encoding +^^^^^^^^^^^^^^^ + +Varint encoding is identical to the ofs-delta encoding method used +within pack files. + +Decoder works such as: + +.... +val = buf[ptr] & 0x7f +while (buf[ptr] & 0x80) { + ptr++ + val = ((val + 1) << 7) | (buf[ptr] & 0x7f) +} +.... + +Ordering +^^^^^^^^ + +Blocks are lexicographically ordered by their first reference. + +Directory/file conflicts +^^^^^^^^^^^^^^^^^^^^^^^^ + +The reftable format accepts both `refs/heads/foo` and +`refs/heads/foo/bar` as distinct references. + +This property is useful for retaining log records in reftable, but may +confuse versions of Git using `$GIT_DIR/refs` directory tree to maintain +references. Users of reftable may choose to continue to reject `foo` and +`foo/bar` type conflicts to prevent problems for peers. + +File format +~~~~~~~~~~~ + +Structure +^^^^^^^^^ + +A reftable file has the following high-level structure: + +.... +first_block { + header + first_ref_block +} +ref_block* +ref_index* +obj_block* +obj_index* +log_block* +log_index* +footer +.... + +A log-only file omits the `ref_block`, `ref_index`, `obj_block` and +`obj_index` sections, containing only the file header and log block: + +.... +first_block { + header +} +log_block* +log_index* +footer +.... + +in a log-only file the first log block immediately follows the file +header, without padding to block alignment. + +Block size +^^^^^^^^^^ + +The file's block size is arbitrarily determined by the writer, and does +not have to be a power of 2. The block size must be larger than the +longest reference name or log entry used in the repository, as +references cannot span blocks. + +Powers of two that are friendly to the virtual memory system or +filesystem (such as 4k or 8k) are recommended. Larger sizes (64k) can +yield better compression, with a possible increased cost incurred by +readers during access. + +The largest block size is `16777215` bytes (15.99 MiB). + +Block alignment +^^^^^^^^^^^^^^^ + +Writers may choose to align blocks at multiples of the block size by +including `padding` filled with NUL bytes at the end of a block to round +out to the chosen alignment. When alignment is used, writers must +specify the alignment with the file header's `block_size` field. + +Block alignment is not required by the file format. Unaligned files must +set `block_size = 0` in the file header, and omit `padding`. Unaligned +files with more than one ref block must include the link:#Ref-index[ref +index] to support fast lookup. Readers must be able to read both aligned +and non-aligned files. + +Very small files (e.g. a single ref block) may omit `padding` and the ref +index to reduce total file size. + +Header (version 1) +^^^^^^^^^^^^^^^^^^ + +A 24-byte header appears at the beginning of the file: + +.... +'REFT' +uint8( version_number = 1 ) +uint24( block_size ) +uint64( min_update_index ) +uint64( max_update_index ) +.... + +Aligned files must specify `block_size` to configure readers with the +expected block alignment. Unaligned files must set `block_size = 0`. + +The `min_update_index` and `max_update_index` describe bounds for the +`update_index` field of all log records in this file. When reftables are +used in a stack for link:#Update-transactions[transactions], these +fields can order the files such that the prior file's +`max_update_index + 1` is the next file's `min_update_index`. + +Header (version 2) +^^^^^^^^^^^^^^^^^^ + +A 28-byte header appears at the beginning of the file: + +.... +'REFT' +uint8( version_number = 2 ) +uint24( block_size ) +uint64( min_update_index ) +uint64( max_update_index ) +uint32( hash_id ) +.... + +The header is identical to `version_number=1`, with the 4-byte hash ID +("sha1" for SHA1 and "s256" for SHA-256) append to the header. + +For maximum backward compatibility, it is recommended to use version 1 when +writing SHA1 reftables. + +First ref block +^^^^^^^^^^^^^^^ + +The first ref block shares the same block as the file header, and is 24 +bytes smaller than all other blocks in the file. The first block +immediately begins after the file header, at position 24. + +If the first block is a log block (a log-only file), its block header +begins immediately at position 24. + +Ref block format +^^^^^^^^^^^^^^^^ + +A ref block is written as: + +.... +'r' +uint24( block_len ) +ref_record+ +uint24( restart_offset )+ +uint16( restart_count ) + +padding? +.... + +Blocks begin with `block_type = 'r'` and a 3-byte `block_len` which +encodes the number of bytes in the block up to, but not including the +optional `padding`. This is always less than or equal to the file's +block size. In the first ref block, `block_len` includes 24 bytes for +the file header. + +The 2-byte `restart_count` stores the number of entries in the +`restart_offset` list, which must not be empty. Readers can use +`restart_count` to binary search between restarts before starting a +linear scan. + +Exactly `restart_count` 3-byte `restart_offset` values precedes the +`restart_count`. Offsets are relative to the start of the block and +refer to the first byte of any `ref_record` whose name has not been +prefix compressed. Entries in the `restart_offset` list must be sorted, +ascending. Readers can start linear scans from any of these records. + +A variable number of `ref_record` fill the middle of the block, +describing reference names and values. The format is described below. + +As the first ref block shares the first file block with the file header, +all `restart_offset` in the first block are relative to the start of the +file (position 0), and include the file header. This forces the first +`restart_offset` to be `28`. + +ref record +++++++++++ + +A `ref_record` describes a single reference, storing both the name and +its value(s). Records are formatted as: + +.... +varint( prefix_length ) +varint( (suffix_length << 3) | value_type ) +suffix +varint( update_index_delta ) +value? +.... + +The `prefix_length` field specifies how many leading bytes of the prior +reference record's name should be copied to obtain this reference's +name. This must be 0 for the first reference in any block, and also must +be 0 for any `ref_record` whose offset is listed in the `restart_offset` +table at the end of the block. + +Recovering a reference name from any `ref_record` is a simple concat: + +.... +this_name = prior_name[0..prefix_length] + suffix +.... + +The `suffix_length` value provides the number of bytes available in +`suffix` to copy from `suffix` to complete the reference name. + +The `update_index` that last modified the reference can be obtained by +adding `update_index_delta` to the `min_update_index` from the file +header: `min_update_index + update_index_delta`. + +The `value` follows. Its format is determined by `value_type`, one of +the following: + +* `0x0`: deletion; no value data (see transactions, below) +* `0x1`: one object name; value of the ref +* `0x2`: two object names; value of the ref, peeled target +* `0x3`: symbolic reference: `varint( target_len ) target` + +Symbolic references use `0x3`, followed by the complete name of the +reference target. No compression is applied to the target name. + +Types `0x4..0x7` are reserved for future use. + +Ref index +^^^^^^^^^ + +The ref index stores the name of the last reference from every ref block +in the file, enabling reduced disk seeks for lookups. Any reference can +be found by searching the index, identifying the containing block, and +searching within that block. + +The index may be organized into a multi-level index, where the 1st level +index block points to additional ref index blocks (2nd level), which may +in turn point to either additional index blocks (e.g. 3rd level) or ref +blocks (leaf level). Disk reads required to access a ref go up with +higher index levels. Multi-level indexes may be required to ensure no +single index block exceeds the file format's max block size of +`16777215` bytes (15.99 MiB). To achieve constant O(1) disk seeks for +lookups the index must be a single level, which is permitted to exceed +the file's configured block size, but not the format's max block size of +15.99 MiB. + +If present, the ref index block(s) appears after the last ref block. + +If there are at least 4 ref blocks, a ref index block should be written +to improve lookup times. Cold reads using the index require 2 disk reads +(read index, read block), and binary searching < 4 blocks also requires +<= 2 reads. Omitting the index block from smaller files saves space. + +If the file is unaligned and contains more than one ref block, the ref +index must be written. + +Index block format: + +.... +'i' +uint24( block_len ) +index_record+ +uint24( restart_offset )+ +uint16( restart_count ) + +padding? +.... + +The index blocks begin with `block_type = 'i'` and a 3-byte `block_len` +which encodes the number of bytes in the block, up to but not including +the optional `padding`. + +The `restart_offset` and `restart_count` fields are identical in format, +meaning and usage as in ref blocks. + +To reduce the number of reads required for random access in very large +files the index block may be larger than other blocks. However, readers +must hold the entire index in memory to benefit from this, so it's a +time-space tradeoff in both file size and reader memory. + +Increasing the file's block size decreases the index size. Alternatively +a multi-level index may be used, keeping index blocks within the file's +block size, but increasing the number of blocks that need to be +accessed. + +index record +++++++++++++ + +An index record describes the last entry in another block. Index records +are written as: + +.... +varint( prefix_length ) +varint( (suffix_length << 3) | 0 ) +suffix +varint( block_position ) +.... + +Index records use prefix compression exactly like `ref_record`. + +Index records store `block_position` after the suffix, specifying the +absolute position in bytes (from the start of the file) of the block +that ends with this reference. Readers can seek to `block_position` to +begin reading the block header. + +Readers must examine the block header at `block_position` to determine +if the next block is another level index block, or the leaf-level ref +block. + +Reading the index ++++++++++++++++++ + +Readers loading the ref index must first read the footer (below) to +obtain `ref_index_position`. If not present, the position will be 0. The +`ref_index_position` is for the 1st level root of the ref index. + +Obj block format +^^^^^^^^^^^^^^^^ + +Object blocks are optional. Writers may choose to omit object blocks, +especially if readers will not use the object name to ref mapping. + +Object blocks use unique, abbreviated 2-32 object name keys, mapping to +ref blocks containing references pointing to that object directly, or as +the peeled value of an annotated tag. Like ref blocks, object blocks use +the file's standard block size. The abbreviation length is available in +the footer as `obj_id_len`. + +To save space in small files, object blocks may be omitted if the ref +index is not present, as brute force search will only need to read a few +ref blocks. When missing, readers should brute force a linear search of +all references to lookup by object name. + +An object block is written as: + +.... +'o' +uint24( block_len ) +obj_record+ +uint24( restart_offset )+ +uint16( restart_count ) + +padding? +.... + +Fields are identical to ref block. Binary search using the restart table +works the same as in reference blocks. + +Because object names are abbreviated by writers to the shortest unique +abbreviation within the reftable, obj key lengths have a variable length. Their +length must be at least 2 bytes. Readers must compare only for common prefix +match within an obj block or obj index. + +obj record +++++++++++ + +An `obj_record` describes a single object abbreviation, and the blocks +containing references using that unique abbreviation: + +.... +varint( prefix_length ) +varint( (suffix_length << 3) | cnt_3 ) +suffix +varint( cnt_large )? +varint( position_delta )* +.... + +Like in reference blocks, abbreviations are prefix compressed within an +obj block. On large reftables with many unique objects, higher block +sizes (64k), and higher restart interval (128), a `prefix_length` of 2 +or 3 and `suffix_length` of 3 may be common in obj records (unique +abbreviation of 5-6 raw bytes, 10-12 hex digits). + +Each record contains `position_count` number of positions for matching +ref blocks. For 1-7 positions the count is stored in `cnt_3`. When +`cnt_3 = 0` the actual count follows in a varint, `cnt_large`. + +The use of `cnt_3` bets most objects are pointed to by only a single +reference, some may be pointed to by a couple of references, and very +few (if any) are pointed to by more than 7 references. + +A special case exists when `cnt_3 = 0` and `cnt_large = 0`: there are no +`position_delta`, but at least one reference starts with this +abbreviation. A reader that needs exact reference names must scan all +references to find which specific references have the desired object. +Writers should use this format when the `position_delta` list would have +overflowed the file's block size due to a high number of references +pointing to the same object. + +The first `position_delta` is the position from the start of the file. +Additional `position_delta` entries are sorted ascending and relative to +the prior entry, e.g. a reader would perform: + +.... +pos = position_delta[0] +prior = pos +for (j = 1; j < position_count; j++) { + pos = prior + position_delta[j] + prior = pos +} +.... + +With a position in hand, a reader must linearly scan the ref block, +starting from the first `ref_record`, testing each reference's object names +(for `value_type = 0x1` or `0x2`) for full equality. Faster searching by +object name within a single ref block is not supported by the reftable format. +Smaller block sizes reduce the number of candidates this step must +consider. + +Obj index +^^^^^^^^^ + +The obj index stores the abbreviation from the last entry for every obj +block in the file, enabling reduced disk seeks for all lookups. It is +formatted exactly the same as the ref index, but refers to obj blocks. + +The obj index should be present if obj blocks are present, as obj blocks +should only be written in larger files. + +Readers loading the obj index must first read the footer (below) to +obtain `obj_index_position`. If not present, the position will be 0. + +Log block format +^^^^^^^^^^^^^^^^ + +Unlike ref and obj blocks, log blocks are always unaligned. + +Log blocks are variable in size, and do not match the `block_size` +specified in the file header or footer. Writers should choose an +appropriate buffer size to prepare a log block for deflation, such as +`2 * block_size`. + +A log block is written as: + +.... +'g' +uint24( block_len ) +zlib_deflate { + log_record+ + uint24( restart_offset )+ + uint16( restart_count ) +} +.... + +Log blocks look similar to ref blocks, except `block_type = 'g'`. + +The 4-byte block header is followed by the deflated block contents using +zlib deflate. The `block_len` in the header is the inflated size +(including 4-byte block header), and should be used by readers to +preallocate the inflation output buffer. A log block's `block_len` may +exceed the file's block size. + +Offsets within the log block (e.g. `restart_offset`) still include the +4-byte header. Readers may prefer prefixing the inflation output buffer +with the 4-byte header. + +Within the deflate container, a variable number of `log_record` describe +reference changes. The log record format is described below. See ref +block format (above) for a description of `restart_offset` and +`restart_count`. + +Because log blocks have no alignment or padding between blocks, readers +must keep track of the bytes consumed by the inflater to know where the +next log block begins. + +log record +++++++++++ + +Log record keys are structured as: + +.... +ref_name '\0' reverse_int64( update_index ) +.... + +where `update_index` is the unique transaction identifier. The +`update_index` field must be unique within the scope of a `ref_name`. +See the update transactions section below for further details. + +The `reverse_int64` function inverses the value so lexicographical +ordering the network byte order encoding sorts the more recent records +with higher `update_index` values first: + +.... +reverse_int64(int64 t) { + return 0xffffffffffffffff - t; +} +.... + +Log records have a similar starting structure to ref and index records, +utilizing the same prefix compression scheme applied to the log record +key described above. + +.... + varint( prefix_length ) + varint( (suffix_length << 3) | log_type ) + suffix + log_data { + old_id + new_id + varint( name_length ) name + varint( email_length ) email + varint( time_seconds ) + sint16( tz_offset ) + varint( message_length ) message + }? +.... + +Log record entries use `log_type` to indicate what follows: + +* `0x0`: deletion; no log data. +* `0x1`: standard git reflog data using `log_data` above. + +The `log_type = 0x0` is mostly useful for `git stash drop`, removing an +entry from the reflog of `refs/stash` in a transaction file (below), +without needing to rewrite larger files. Readers reading a stack of +reflogs must treat this as a deletion. + +For `log_type = 0x1`, the `log_data` section follows +linkgit:git-update-ref[1] logging and includes: + +* two object names (old id, new id) +* varint string of committer's name +* varint string of committer's email +* varint time in seconds since epoch (Jan 1, 1970) +* 2-byte timezone offset in minutes (signed) +* varint string of message + +`tz_offset` is the absolute number of minutes from GMT the committer was +at the time of the update. For example `GMT-0800` is encoded in reftable +as `sint16(-480)` and `GMT+0230` is `sint16(150)`. + +The committer email does not contain `<` or `>`, it's the value normally +found between the `<>` in a git commit object header. + +The `message_length` may be 0, in which case there was no message +supplied for the update. + +Contrary to traditional reflog (which is a file), renames are encoded as +a combination of ref deletion and ref creation. A deletion is a log +record with a zero new_id, and a creation is a log record with a zero old_id. + +Reading the log ++++++++++++++++ + +Readers accessing the log must first read the footer (below) to +determine the `log_position`. The first block of the log begins at +`log_position` bytes since the start of the file. The `log_position` is +not block aligned. + +Importing logs +++++++++++++++ + +When importing from `$GIT_DIR/logs` writers should globally order all +log records roughly by timestamp while preserving file order, and assign +unique, increasing `update_index` values for each log line. Newer log +records get higher `update_index` values. + +Although an import may write only a single reftable file, the reftable +file must span many unique `update_index`, as each log line requires its +own `update_index` to preserve semantics. + +Log index +^^^^^^^^^ + +The log index stores the log key +(`refname \0 reverse_int64(update_index)`) for the last log record of +every log block in the file, supporting bounded-time lookup. + +A log index block must be written if 2 or more log blocks are written to +the file. If present, the log index appears after the last log block. +There is no padding used to align the log index to block alignment. + +Log index format is identical to ref index, except the keys are 9 bytes +longer to include `'\0'` and the 8-byte `reverse_int64(update_index)`. +Records use `block_position` to refer to the start of a log block. + +Reading the index ++++++++++++++++++ + +Readers loading the log index must first read the footer (below) to +obtain `log_index_position`. If not present, the position will be 0. + +Footer +^^^^^^ + +After the last block of the file, a file footer is written. It begins +like the file header, but is extended with additional data. + +.... + HEADER + + uint64( ref_index_position ) + uint64( (obj_position << 5) | obj_id_len ) + uint64( obj_index_position ) + + uint64( log_position ) + uint64( log_index_position ) + + uint32( CRC-32 of above ) +.... + +If a section is missing (e.g. ref index) the corresponding position +field (e.g. `ref_index_position`) will be 0. + +* `obj_position`: byte position for the first obj block. +* `obj_id_len`: number of bytes used to abbreviate object names in +obj blocks. +* `log_position`: byte position for the first log block. +* `ref_index_position`: byte position for the start of the ref index. +* `obj_index_position`: byte position for the start of the obj index. +* `log_index_position`: byte position for the start of the log index. + +The size of the footer is 68 bytes for version 1, and 72 bytes for +version 2. + +Reading the footer +++++++++++++++++++ + +Readers must first read the file start to determine the version +number. Then they seek to `file_length - FOOTER_LENGTH` to access the +footer. A trusted external source (such as `stat(2)`) is necessary to +obtain `file_length`. When reading the footer, readers must verify: + +* 4-byte magic is correct +* 1-byte version number is recognized +* 4-byte CRC-32 matches the other 64 bytes (including magic, and +version) + +Once verified, the other fields of the footer can be accessed. + +Empty tables +++++++++++++ + +A reftable may be empty. In this case, the file starts with a header +and is immediately followed by a footer. + +Binary search +^^^^^^^^^^^^^ + +Binary search within a block is supported by the `restart_offset` fields +at the end of the block. Readers can binary search through the restart +table to locate between which two restart points the sought reference or +key should appear. + +Each record identified by a `restart_offset` stores the complete key in +the `suffix` field of the record, making the compare operation during +binary search straightforward. + +Once a restart point lexicographically before the sought reference has +been identified, readers can linearly scan through the following record +entries to locate the sought record, terminating if the current record +sorts after (and therefore the sought key is not present). + +Restart point selection ++++++++++++++++++++++++ + +Writers determine the restart points at file creation. The process is +arbitrary, but every 16 or 64 records is recommended. Every 16 may be +more suitable for smaller block sizes (4k or 8k), every 64 for larger +block sizes (64k). + +More frequent restart points reduces prefix compression and increases +space consumed by the restart table, both of which increase file size. + +Less frequent restart points makes prefix compression more effective, +decreasing overall file size, with increased penalties for readers +walking through more records after the binary search step. + +A maximum of `65535` restart points per block is supported. + +Considerations +~~~~~~~~~~~~~~ + +Lightweight refs dominate +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The reftable format assumes the vast majority of references are single +object names valued with common prefixes, such as Gerrit Code Review's +`refs/changes/` namespace, GitHub's `refs/pulls/` namespace, or many +lightweight tags in the `refs/tags/` namespace. + +Annotated tags storing the peeled object cost an additional object name per +reference. + +Low overhead +^^^^^^^^^^^^ + +A reftable with very few references (e.g. git.git with 5 heads) is 269 +bytes for reftable, vs. 332 bytes for packed-refs. This supports +reftable scaling down for transaction logs (below). + +Block size +^^^^^^^^^^ + +For a Gerrit Code Review type repository with many change refs, larger +block sizes (64 KiB) and less frequent restart points (every 64) yield +better compression due to more references within the block compressing +against the prior reference. + +Larger block sizes reduce the index size, as the reftable will require +fewer blocks to store the same number of references. + +Minimal disk seeks +^^^^^^^^^^^^^^^^^^ + +Assuming the index block has been loaded into memory, binary searching +for any single reference requires exactly 1 disk seek to load the +containing block. + +Scans and lookups dominate +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Scanning all references and lookup by name (or namespace such as +`refs/heads/`) are the most common activities performed on repositories. +Object names are stored directly with references to optimize this use case. + +Logs are infrequently read +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Logs are infrequently accessed, but can be large. Deflating log blocks +saves disk space, with some increased penalty at read time. + +Logs are stored in an isolated section from refs, reducing the burden on +reference readers that want to ignore logs. Further, historical logs can +be isolated into log-only files. + +Logs are read backwards +^^^^^^^^^^^^^^^^^^^^^^^ + +Logs are frequently accessed backwards (most recent N records for master +to answer `master@{4}`), so log records are grouped by reference, and +sorted descending by update index. + +Repository format +~~~~~~~~~~~~~~~~~ + +Version 1 +^^^^^^^^^ + +A repository must set its `$GIT_DIR/config` to configure reftable: + +.... +[core] + repositoryformatversion = 1 +[extensions] + refStorage = reftable +.... + +Layout +^^^^^^ + +A collection of reftable files are stored in the `$GIT_DIR/reftable/` directory. +Their names should have a random element, such that each filename is globally +unique; this helps avoid spurious failures on Windows, where open files cannot +be removed or overwritten. It suggested to use +`${min_update_index}-${max_update_index}-${random}.ref` as a naming convention. + +Log-only files use the `.log` extension, while ref-only and mixed ref +and log files use `.ref`. extension. + +The stack ordering file is `$GIT_DIR/reftable/tables.list` and lists the +current files, one per line, in order, from oldest (base) to newest +(most recent): + +.... +$ cat .git/reftable/tables.list +00000001-00000001-RANDOM1.log +00000002-00000002-RANDOM2.ref +00000003-00000003-RANDOM3.ref +.... + +Readers must read `$GIT_DIR/reftable/tables.list` to determine which +files are relevant right now, and search through the stack in reverse +order (last reftable is examined first). + +Reftable files not listed in `tables.list` may be new (and about to be +added to the stack by the active writer), or ancient and ready to be +pruned. + +Backward compatibility +^^^^^^^^^^^^^^^^^^^^^^ + +Older clients should continue to recognize the directory as a git +repository so they don't look for an enclosing repository in parent +directories. To this end, a reftable-enabled repository must contain the +following dummy files + +* `.git/HEAD`, a regular file containing `ref: refs/heads/.invalid`. +* `.git/refs/`, a directory +* `.git/refs/heads`, a regular file + +Readers +^^^^^^^ + +Readers can obtain a consistent snapshot of the reference space by +following: + +1. Open and read the `tables.list` file. +2. Open each of the reftable files that it mentions. +3. If any of the files is missing, goto 1. +4. Read from the now-open files as long as necessary. + +Update transactions +^^^^^^^^^^^^^^^^^^^ + +Although reftables are immutable, mutations are supported by writing a +new reftable and atomically appending it to the stack: + +1. Acquire `tables.list.lock`. +2. Read `tables.list` to determine current reftables. +3. Select `update_index` to be most recent file's +`max_update_index + 1`. +4. Prepare temp reftable `tmp_XXXXXX`, including log entries. +5. Rename `tmp_XXXXXX` to `${update_index}-${update_index}-${random}.ref`. +6. Copy `tables.list` to `tables.list.lock`, appending file from (5). +7. Rename `tables.list.lock` to `tables.list`. + +During step 4 the new file's `min_update_index` and `max_update_index` +are both set to the `update_index` selected by step 3. All log records +for the transaction use the same `update_index` in their keys. This +enables later correlation of which references were updated by the same +transaction. + +Because a single `tables.list.lock` file is used to manage locking, the +repository is single-threaded for writers. Writers may have to busy-spin +(with backoff) around creating `tables.list.lock`, for up to an +acceptable wait period, aborting if the repository is too busy to +mutate. Application servers wrapped around repositories (e.g. Gerrit +Code Review) can layer their own lock/wait queue to improve fairness to +writers. + +Reference deletions +^^^^^^^^^^^^^^^^^^^ + +Deletion of any reference can be explicitly stored by setting the `type` +to `0x0` and omitting the `value` field of the `ref_record`. This serves +as a tombstone, overriding any assertions about the existence of the +reference from earlier files in the stack. + +Compaction +^^^^^^^^^^ + +A partial stack of reftables can be compacted by merging references +using a straightforward merge join across reftables, selecting the most +recent value for output, and omitting deleted references that do not +appear in remaining, lower reftables. + +A compacted reftable should set its `min_update_index` to the smallest +of the input files' `min_update_index`, and its `max_update_index` +likewise to the largest input `max_update_index`. + +For sake of illustration, assume the stack currently consists of +reftable files (from oldest to newest): A, B, C, and D. The compactor is +going to compact B and C, leaving A and D alone. + +1. Obtain lock `tables.list.lock` and read the `tables.list` file. +2. Obtain locks `B.lock` and `C.lock`. Ownership of these locks +prevents other processes from trying to compact these files. +3. Release `tables.list.lock`. +4. Compact `B` and `C` into a temp file +`${min_update_index}-${max_update_index}_XXXXXX`. +5. Reacquire lock `tables.list.lock`. +6. Verify that `B` and `C` are still in the stack, in that order. This +should always be the case, assuming that other processes are adhering to +the locking protocol. +7. Rename `${min_update_index}-${max_update_index}_XXXXXX` to +`${min_update_index}-${max_update_index}-${random}.ref`. +8. Write the new stack to `tables.list.lock`, replacing `B` and `C` +with the file from (4). +9. Rename `tables.list.lock` to `tables.list`. +10. Delete `B` and `C`, perhaps after a short sleep to avoid forcing +readers to backtrack. + +This strategy permits compactions to proceed independently of updates. + +Each reftable (compacted or not) is uniquely identified by its name, so +open reftables can be cached by their name. + +Windows +^^^^^^^ + +On windows, and other systems that do not allow deleting or renaming to open +files, compaction may succeed, but other readers may prevent obsolete tables +from being deleted. + +On these platforms, the following strategy can be followed: on closing a +reftable stack, reload `tables.list`, and delete any tables no longer mentioned +in `tables.list`. + +Irregular program exit may still leave about unused files. In this case, a +cleanup operation should proceed as follows: + +* take a lock `tables.list.lock` to prevent concurrent modifications +* refresh the reftable stack, by reading `tables.list` +* for each `*.ref` file, remove it if +** it is not mentioned in `tables.list`, and +** its max update_index is not beyond the max update_index of the stack + + +Alternatives considered +~~~~~~~~~~~~~~~~~~~~~~~ + +bzip packed-refs +^^^^^^^^^^^^^^^^ + +`bzip2` can significantly shrink a large packed-refs file (e.g. 62 MiB +compresses to 23 MiB, 37%). However the bzip format does not support +random access to a single reference. Readers must inflate and discard +while performing a linear scan. + +Breaking packed-refs into chunks (individually compressing each chunk) +would reduce the amount of data a reader must inflate, but still leaves +the problem of indexing chunks to support readers efficiently locating +the correct chunk. + +Given the compression achieved by reftable's encoding, it does not seem +necessary to add the complexity of bzip/gzip/zlib. + +Michael Haggerty's alternate format +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Michael Haggerty proposed +link:https://lore.kernel.org/git/CAMy9T_HCnyc1g8XWOOWhe7nN0aEFyyBskV2aOMb_fe%2BwGvEJ7A%40mail.gmail.com/[an +alternate] format to reftable on the Git mailing list. This format uses +smaller chunks, without the restart table, and avoids block alignment +with padding. Reflog entries immediately follow each ref, and are thus +interleaved between refs. + +Performance testing indicates reftable is faster for lookups (51% +faster, 11.2 usec vs. 5.4 usec), although reftable produces a slightly +larger file (+ ~3.2%, 28.3M vs 29.2M): + +[cols=">,>,>,>",options="header",] +|===================================== +|format |size |seek cold |seek hot +|mh-alt |28.3 M |23.4 usec |11.2 usec +|reftable |29.2 M |19.9 usec |5.4 usec +|===================================== + +JGit Ketch RefTree +^^^^^^^^^^^^^^^^^^ + +https://dev.eclipse.org/mhonarc/lists/jgit-dev/msg03073.html[JGit Ketch] +proposed +link:https://lore.kernel.org/git/CAJo%3DhJvnAPNAdDcAAwAvU9C4RVeQdoS3Ev9WTguHx4fD0V_nOg%40mail.gmail.com/[RefTree], +an encoding of references inside Git tree objects stored as part of the +repository's object database. + +The RefTree format adds additional load on the object database storage +layer (more loose objects, more objects in packs), and relies heavily on +the packer's delta compression to save space. Namespaces which are flat +(e.g. thousands of tags in refs/tags) initially create very large loose +objects, and so RefTree does not address the problem of copying many +references to modify a handful. + +Flat namespaces are not efficiently searchable in RefTree, as tree +objects in canonical formatting cannot be binary searched. This fails +the need to handle a large number of references in a single namespace, +such as GitHub's `refs/pulls`, or a project with many tags. + +LMDB +^^^^ + +David Turner proposed +https://lore.kernel.org/git/1455772670-21142-26-git-send-email-dturner@twopensource.com/[using +LMDB], as LMDB is lightweight (64k of runtime code) and GPL-compatible +license. + +A downside of LMDB is its reliance on a single C implementation. This +makes embedding inside JGit (a popular reimplementation of Git) +difficult, and hoisting onto virtual storage (for JGit DFS) virtually +impossible. + +A common format that can be supported by all major Git implementations +(git-core, JGit, libgit2) is strongly preferred. diff --git a/Documentation/technical/remembering-renames.txt b/Documentation/technical/remembering-renames.txt new file mode 100644 index 0000000000..2fd5cc88e0 --- /dev/null +++ b/Documentation/technical/remembering-renames.txt @@ -0,0 +1,671 @@ +Rebases and cherry-picks involve a sequence of merges whose results are +recorded as new single-parent commits. The first parent side of those +merges represent the "upstream" side, and often include a far larger set of +changes than the second parent side. Traditionally, the renames on the +first-parent side of that sequence of merges were repeatedly re-detected +for every merge. This file explains why it is safe and effective during +rebases and cherry-picks to remember renames on the upstream side of +history as an optimization, assuming all merges are automatic and clean +(i.e. no conflicts and not interrupted for user input or editing). + +Outline: + + 0. Assumptions + + 1. How rebasing and cherry-picking work + + 2. Why the renames on MERGE_SIDE1 in any given pick are *always* a + superset of the renames on MERGE_SIDE1 for the next pick. + + 3. Why any rename on MERGE_SIDE1 in any given pick is _almost_ always also + a rename on MERGE_SIDE1 for the next pick + + 4. A detailed description of the the counter-examples to #3. + + 5. Why the special cases in #4 are still fully reasonable to use to pair + up files for three-way content merging in the merge machinery, and why + they do not affect the correctness of the merge. + + 6. Interaction with skipping of "irrelevant" renames + + 7. Additional items that need to be cached + + 8. How directory rename detection interacts with the above and why this + optimization is still safe even if merge.directoryRenames is set to + "true". + + +=== 0. Assumptions === + +There are two assumptions that will hold throughout this document: + + * The upstream side where commits are transplanted to is treated as the + first parent side when rebase/cherry-pick call the merge machinery + + * All merges are fully automatic + +and a third that will hold in sections 2-5 for simplicity, that I'll later +address in section 8: + + * No directory renames occur + + +Let me explain more about each assumption and why I include it: + + +The first assumption is merely for the purposes of making this document +clearer; the optimization implementation does not actually depend upon it. +However, the assumption does hold in all cases because it reflects the way +that both rebase and cherry-pick were implemented; and the implementation +of cherry-pick and rebase are not readily changeable for backwards +compatibility reasons (see for example the discussion of the --ours and +--theirs flag in the documentation of `git checkout`, particularly the +comments about how they behave with rebase). The optimization avoids +checking first-parent-ness, though. It checks the conditions that make the +optimization valid instead, so it would still continue working if someone +changed the parent ordering that cherry-pick and rebase use. But making +this assumption does make this document much clearer and prevents me from +having to repeat every example twice. + +If the second assumption is violated, then the optimization simply is +turned off and thus isn't relevant to consider. The second assumption can +also be stated as "there is no interruption for a user to resolve conflicts +or to just further edit or tweak files". While real rebases and +cherry-picks are often interrupted (either because it's an interactive +rebase where the user requested to stop and edit, or because there were +conflicts that the user needs to resolve), the cache of renames is not +stored on disk, and thus is thrown away as soon as the rebase or cherry +pick stops for the user to resolve the operation. + +The third assumption makes sections 2-5 simpler, and allows people to +understand the basics of why this optimization is safe and effective, and +then I can go back and address the specifics in section 8. It is probably +also worth noting that if directory renames do occur, then the default of +merge.directoryRenames being set to "conflict" means that the operation +will stop for users to resolve the conflicts and the cache will be thrown +away, and thus that there won't be an optimization to apply. So, the only +reason we need to address directory renames specifically, is that some +users will have set merge.directoryRenames to "true" to allow the merges to +continue to proceed automatically. The optimization is still safe with +this config setting, but we have to discuss a few more cases to show why; +this discussion is deferred until section 8. + + +=== 1. How rebasing and cherry-picking work === + +Consider the following setup (from the git-rebase manpage): + + A---B---C topic + / + D---E---F---G main + +After rebasing or cherry-picking topic onto main, this will appear as: + + A'--B'--C' topic + / + D---E---F---G main + +The way the commits A', B', and C' are created is through a series of +merges, where rebase or cherry-pick sequentially uses each of the three +A-B-C commits in a special merge operation. Let's label the three commits +in the merge operation as MERGE_BASE, MERGE_SIDE1, and MERGE_SIDE2. For +this picture, the three commits for each of the three merges would be: + +To create A': + MERGE_BASE: E + MERGE_SIDE1: G + MERGE_SIDE2: A + +To create B': + MERGE_BASE: A + MERGE_SIDE1: A' + MERGE_SIDE2: B + +To create C': + MERGE_BASE: B + MERGE_SIDE1: B' + MERGE_SIDE2: C + +Sometimes, folks are surprised that these three-way merges are done. It +can be useful in understanding these three-way merges to view them in a +slightly different light. For example, in creating C', you can view it as +either: + + * Apply the changes between B & C to B' + * Apply the changes between B & B' to C + +Conceptually the two statements above are the same as a three-way merge of +B, B', and C, at least the parts before you decide to record a commit. + + +=== 2. Why the renames on MERGE_SIDE1 in any given pick are always a === +=== superset of the renames on MERGE_SIDE1 for the next pick. === + +The merge machinery uses the filenames it is fed from MERGE_BASE, +MERGE_SIDE1, and MERGE_SIDE2. It will only move content to a different +filename under one of three conditions: + + * To make both pieces of a conflict available to a user during conflict + resolution (examples: directory/file conflict, add/add type conflict + such as symlink vs. regular file) + + * When MERGE_SIDE1 renames the file. + + * When MERGE_SIDE2 renames the file. + +First, let's remember what commits are involved in the first and second +picks of the cherry-pick or rebase sequence: + +To create A': + MERGE_BASE: E + MERGE_SIDE1: G + MERGE_SIDE2: A + +To create B': + MERGE_BASE: A + MERGE_SIDE1: A' + MERGE_SIDE2: B + +So, in particular, we need to show that the renames between E and G are a +superset of those between A and A'. + +A' is created by the first merge. A' will only have renames for one of the +three reasons listed above. The first case, a conflict, results in a +situation where the cache is dropped and thus this optimization doesn't +take effect, so we need not consider that case. The third case, a rename +on MERGE_SIDE2 (i.e. from G to A), will show up in A' but it also shows up +in A -- therefore when diffing A and A' that path does not show up as a +rename. The only remaining way for renames to show up in A' is for the +rename to come from MERGE_SIDE1. Therefore, all renames between A and A' +are a subset of those between E and G. Equivalently, all renames between E +and G are a superset of those between A and A'. + + +=== 3. Why any rename on MERGE_SIDE1 in any given pick is _almost_ === +=== always also a rename on MERGE_SIDE1 for the next pick. === + +Let's again look at the first two picks: + +To create A': + MERGE_BASE: E + MERGE_SIDE1: G + MERGE_SIDE2: A + +To create B': + MERGE_BASE: A + MERGE_SIDE1: A' + MERGE_SIDE2: B + +Now let's look at any given rename from MERGE_SIDE1 of the first pick, i.e. +any given rename from E to G. Let's use the filenames 'oldfile' and +'newfile' for demonstration purposes. That first pick will function as +follows; when the rename is detected, the merge machinery will do a +three-way content merge of the following: + E:oldfile + G:newfile + A:oldfile +and produce a new result: + A':newfile + +Note above that I've assumed that E->A did not rename oldfile. If that +side did rename, then we most likely have a rename/rename(1to2) conflict +that will cause the rebase or cherry-pick operation to halt and drop the +in-memory cache of renames and thus doesn't need to be considered further. +In the special case that E->A does rename the file but also renames it to +newfile, then there is no conflict from the renaming and the merge can +succeed. In this special case, the rename is not valid to cache because +the second merge will find A:newfile in the MERGE_BASE (see also the new +testcases in t6429 with "rename same file identically" in their +description). So a rename/rename(1to1) needs to be specially handled by +pruning renames from the cache and decrementing the dir_rename_counts in +the current and leading directories associated with those renames. Or, +since these are really rare, one could just take the easy way out and +disable the remembering renames optimization when a rename/rename(1to1) +happens. + +The previous paragraph handled the cases for E->A renaming oldfile, let's +continue assuming that oldfile is not renamed in A. + +As per the diagram for creating B', MERGE_SIDE1 involves the changes from A +to A'. So, we are curious whether A:oldfile and A':newfile will be viewed +as renames. Note that: + + * There will be no A':oldfile (because there could not have been a + G:oldfile as we do not do break detection in the merge machinery and + G:newfile was detected as a rename, and by the construction of the + rename above that merged cleanly, the merge machinery will ensure there + is no 'oldfile' in the result). + + * There will be no A:newfile (if there had been, we would have had a + rename/add conflict). + + * Clearly A:oldfile and A':newfile are "related" (A':newfile came from a + clean three-way content merge involving A:oldfile). + +We can also expound on the third point above, by noting that three-way +content merges can also be viewed as applying the differences between the +base and one side to the other side. Thus we can view A':newfile as +having been created by taking the changes between E:oldfile and G:newfile +(which were detected as being related, i.e. <50% changed) to A:oldfile. + +Thus A:oldfile and A':newfile are just as related as E:oldfile and +G:newfile are -- they have exactly identical differences. Since the latter +were detected as renames, A:oldfile and A':newfile should also be +detectable as renames almost always. + + +=== 4. A detailed description of the counter-examples to #3. === + +We already noted in section 3 that rename/rename(1to1) (i.e. both sides +renaming a file the same way) was one counter-example. The more +interesting bit, though, is why did we need to use the "almost" qualifier +when stating that A:oldfile and A':newfile are "almost" always detectable +as renames? + +Let's repeat an earlier point that section 3 made: + + A':newfile was created by applying the changes between E:oldfile and + G:newfile to A:oldfile. The changes between E:oldfile and G:newfile were + <50% of the size of E:oldfile. + +If those changes that were <50% of the size of E:oldfile are also <50% of +the size of A:oldfile, then A:oldfile and A':newfile will be detectable as +renames. However, if there is a dramatic size reduction between E:oldfile +and A:oldfile (but the changes between E:oldfile, G:newfile, and A:oldfile +still somehow merge cleanly), then traditional rename detection would not +detect A:oldfile and A':newfile as renames. + +Here's an example where that can happen: + * E:oldfile had 20 lines + * G:newfile added 10 new lines at the beginning of the file + * A:oldfile kept the first 3 lines of the file, and deleted all the rest +then + => A':newfile would have 13 lines, 3 of which matches those in A:oldfile. +E:oldfile -> G:newfile would be detected as a rename, but A:oldfile and +A':newfile would not be. + + +=== 5. Why the special cases in #4 are still fully reasonable to use to === +=== pair up files for three-way content merging in the merge machinery, === +=== and why they do not affect the correctness of the merge. === + +In the rename/rename(1to1) case, A:newfile and A':newfile are not renames +since they use the *same* filename. However, files with the same filename +are obviously fine to pair up for three-way content merging (the merge +machinery has never employed break detection). The interesting +counter-example case is thus not the rename/rename(1to1) case, but the case +where A did not rename oldfile. That was the case that we spent most of +the time discussing in sections 3 and 4. The remainder of this section +will be devoted to that case as well. + +So, even if A:oldfile and A':newfile aren't detectable as renames, why is +it still reasonable to pair them up for three-way content merging in the +merge machinery? There are multiple reasons: + + * As noted in sections 3 and 4, the diff between A:oldfile and A':newfile + is *exactly* the same as the diff between E:oldfile and G:newfile. The + latter pair were detected as renames, so it seems unlikely to surprise + users for us to treat A:oldfile and A':newfile as renames. + + * In fact, "oldfile" and "newfile" were at one point detected as renames + due to how they were constructed in the E..G chain. And we used that + information once already in this rebase/cherry-pick. I think users + would be unlikely to be surprised at us continuing to treat the files + as renames and would quickly understand why we had done so. + + * Marking or declaring files as renames is *not* the end goal for merges. + Merges use renames to determine which files make sense to be paired up + for three-way content merges. + + * A:oldfile and A':newfile were _already_ paired up in a three-way + content merge; that is how A':newfile was created. In fact, that + three-way content merge was clean. So using them again in a later + three-way content merge seems very reasonable. + +However, the above is focusing on the common scenarios. Let's try to look +at all possible unusual scenarios and compare without the optimization to +with the optimization. Consider the following theoretical cases; we will +then dive into each to determine which of them are possible, +and if so, what they mean: + + 1. Without the optimization, the second merge results in a conflict. + With the optimization, the second merge also results in a conflict. + Questions: Are the conflicts confusingly different? Better in one case? + + 2. Without the optimization, the second merge results in NO conflict. + With the optimization, the second merge also results in NO conflict. + Questions: Are the merges the same? + + 3. Without the optimization, the second merge results in a conflict. + With the optimization, the second merge results in NO conflict. + Questions: Possible? Bug, bugfix, or something else? + + 4. Without the optimization, the second merge results in NO conflict. + With the optimization, the second merge results in a conflict. + Questions: Possible? Bug, bugfix, or something else? + +I'll consider all four cases, but out of order. + +The fourth case is impossible. For the code without the remembering +renames optimization to not get a conflict, B:oldfile would need to exactly +match A:oldfile -- if it doesn't, there would be a modify/delete conflict. +If A:oldfile matches B:oldfile exactly, then a three-way content merge +between A:oldfile, A':newfile, and B:oldfile would have no conflict and +just give us the version of newfile from A' as the result. + +From the same logic as the above paragraph, the second case would indeed +result in identical merges. When A:oldfile exactly matches B:oldfile, an +undetected rename would say, "Oh, I see one side didn't modify 'oldfile' +and the other side deleted it. I'll delete it. And I see you have this +brand new file named 'newfile' in A', so I'll keep it." That gives the +same results as three-way content merging A:oldfile, A':newfile, and +B:oldfile -- a removal of oldfile with the version of newfile from A' +showing up in the result. + +The third case is interesting. It means that A:oldfile and A':newfile were +not just similar enough, but that the changes between them did not conflict +with the changes between A:oldfile and B:oldfile. This would validate our +hunch that the files were similar enough to be used in a three-way content +merge, and thus seems entirely correct for us to have used them that way. +(Sidenote: One particular example here may be enlightening. Let's say that +B was an immediate revert of A. B clearly would have been a clean revert +of A, since A was B's immediate parent. One would assume that if you can +pick a commit, you should also be able to cherry-pick its immediate revert. +However, this is one of those funny corner cases; without this +optimization, we just successfully picked a commit cleanly, but we are +unable to cherry-pick its immediate revert due to the size differences +between E:oldfile and A:oldfile.) + +That leaves only the first case to consider -- when we get conflicts both +with or without the optimization. Without the optimization, we'll have a +modify/delete conflict, where both A':newfile and B:oldfile are left in the +tree for the user to deal with and no hints about the potential similarity +between the two. With the optimization, we'll have a three-way content +merged A:oldfile, A':newfile, and B:oldfile with conflict markers +suggesting we thought the files were related but giving the user the chance +to resolve. As noted above, I don't think users will find us treating +'oldfile' and 'newfile' as related as a surprise since they were between E +and G. In any event, though, this case shouldn't be concerning since we +hit a conflict in both cases, told the user what we know, and asked them to +resolve it. + +So, in summary, case 4 is impossible, case 2 yields the same behavior, and +cases 1 and 3 seem to provide as good or better behavior with the +optimization than without. + + +=== 6. Interaction with skipping of "irrelevant" renames === + +Previous optimizations involved skipping rename detection for paths +considered to be "irrelevant". See for example the following commits: + + * 32a56dfb99 ("merge-ort: precompute subset of sources for which we + need rename detection", 2021-03-11) + * 2fd9eda462 ("merge-ort: precompute whether directory rename + detection is needed", 2021-03-11) + * 9bd342137e ("diffcore-rename: determine which relevant_sources are + no longer relevant", 2021-03-13) + +Relevance is always determined by what the _other_ side of history has +done, in terms of modifing a file that our side renamed, or adding a +file to a directory which our side renamed. This means that a path +that is "irrelevant" when picking the first commit of a series in a +rebase or cherry-pick, may suddenly become "relevant" when picking the +next commit. + +The upshot of this is that we can only cache rename detection results +for relevant paths, and need to re-check relevance in subsequent +commits. If those subsequent commits have additional paths that are +relevant for rename detection, then we will need to redo rename +detection -- though we can limit it to the paths for which we have not +already detected renames. + + +=== 7. Additional items that need to be cached === + +It turns out we have to cache more than just renames; we also cache: + + A) non-renames (i.e. unpaired deletes) + B) counts of renames within directories + C) sources that were marked as RELEVANT_LOCATION, but which were + downgraded to RELEVANT_NO_MORE + D) the toplevel trees involved in the merge + +These are all stored in struct rename_info, and respectively appear in + * cached_pairs (along side actual renames, just with a value of NULL) + * dir_rename_counts + * cached_irrelevant + * merge_trees + +The reason for (A) comes from the irrelevant renames skipping +optimization discussed in section 6. The fact that irrelevant renames +are skipped means we only get a subset of the potential renames +detected and subsequent commits may need to run rename detection on +the upstream side on a subset of the remaining renames (to get the +renames that are relevant for that later commit). Since unpaired +deletes are involved in rename detection too, we don't want to +repeatedly check that those paths remain unpaired on the upstream side +with every commit we are transplanting. + +The reason for (B) is that diffcore_rename_extended() is what +generates the counts of renames by directory which is needed in +directory rename detection, and if we don't run +diffcore_rename_extended() again then we need to have the output from +it, including dir_rename_counts, from the previous run. + +The reason for (C) is that merge-ort's tree traversal will again think +those paths are relevant (marking them as RELEVANT_LOCATION), but the +fact that they were downgraded to RELEVANT_NO_MORE means that +dir_rename_counts already has the information we need for directory +rename detection. (A path which becomes RELEVANT_CONTENT in a +subsequent commit will be removed from cached_irrelevant.) + +The reason for (D) is that is how we determine whether the remember +renames optimization can be used. In particular, remembering that our +sequence of merges looks like: + + Merge 1: + MERGE_BASE: E + MERGE_SIDE1: G + MERGE_SIDE2: A + => Creates A' + + Merge 2: + MERGE_BASE: A + MERGE_SIDE1: A' + MERGE_SIDE2: B + => Creates B' + +It is the fact that the trees A and A' appear both in Merge 1 and in +Merge 2, with A as a parent of A' that allows this optimization. So +we store the trees to compare with what we are asked to merge next +time. + + +=== 8. How directory rename detection interacts with the above and === +=== why this optimization is still safe even if === +=== merge.directoryRenames is set to "true". === + +As noted in the assumptions section: + + """ + ...if directory renames do occur, then the default of + merge.directoryRenames being set to "conflict" means that the operation + will stop for users to resolve the conflicts and the cache will be + thrown away, and thus that there won't be an optimization to apply. + So, the only reason we need to address directory renames specifically, + is that some users will have set merge.directoryRenames to "true" to + allow the merges to continue to proceed automatically. + """ + +Let's remember that we need to look at how any given pick affects the next +one. So let's again use the first two picks from the diagram in section +one: + + First pick does this three-way merge: + MERGE_BASE: E + MERGE_SIDE1: G + MERGE_SIDE2: A + => creates A' + + Second pick does this three-way merge: + MERGE_BASE: A + MERGE_SIDE1: A' + MERGE_SIDE2: B + => creates B' + +Now, directory rename detection exists so that if one side of history +renames a directory, and the other side adds a new file to the old +directory, then the merge (with merge.directoryRenames=true) can move the +file into the new directory. There are two qualitatively different ways to +add a new file to an old directory: create a new file, or rename a file +into that directory. Also, directory renames can be done on either side of +history, so there are four cases to consider: + + * MERGE_SIDE1 renames old dir, MERGE_SIDE2 adds new file to old dir + * MERGE_SIDE1 renames old dir, MERGE_SIDE2 renames file into old dir + * MERGE_SIDE1 adds new file to old dir, MERGE_SIDE2 renames old dir + * MERGE_SIDE1 renames file into old dir, MERGE_SIDE2 renames old dir + +One last note before we consider these four cases: There are some +important properties about how we implement this optimization with +respect to directory rename detection that we need to bear in mind +while considering all of these cases: + + * rename caching occurs *after* applying directory renames + + * a rename created by directory rename detection is recorded for the side + of history that did the directory rename. + + * dir_rename_counts, the nested map of + {oldname => {newname => count}}, + is cached between runs as well. This basically means that directory + rename detection is also cached, though only on the side of history + that we cache renames for (MERGE_SIDE1 as far as this document is + concerned; see the assumptions section). Two interesting sub-notes + about these counts: + + * If we need to perform rename-detection again on the given side (e.g. + some paths are relevant for rename detection that weren't before), + then we clear dir_rename_counts and recompute it, making use of + cached_pairs. The reason it is important to do this is optimizations + around RELEVANT_LOCATION exist to prevent us from computing + unnecessary renames for directory rename detection and from computing + dir_rename_counts for irrelevant directories; but those same renames + or directories may become necessary for subsequent merges. The + easiest way to "fix up" dir_rename_counts in such cases is to just + recompute it. + + * If we prune rename/rename(1to1) entries from the cache, then we also + need to update dir_rename_counts to decrement the counts for the + involved directory and any relevant parent directories (to undo what + update_dir_rename_counts() in diffcore-rename.c incremented when the + rename was initially found). If we instead just disable the + remembering renames optimization when the exceedingly rare + rename/rename(1to1) cases occur, then dir_rename_counts will get + re-computed the next time rename detection occurs, as noted above. + + * the side with multiple commits to pick, is the side of history that we + do NOT cache renames for. Thus, there are no additional commits to + change the number of renames in a directory, except for those done by + directory rename detection (which always pad the majority). + + * the "renames" we cache are modified slightly by any directory rename, + as noted below. + +Now, with those notes out of the way, let's go through the four cases +in order: + +Case 1: MERGE_SIDE1 renames old dir, MERGE_SIDE2 adds new file to old dir + + This case looks like this: + + MERGE_BASE: E, Has olddir/ + MERGE_SIDE1: G, Renames olddir/ -> newdir/ + MERGE_SIDE2: A, Adds olddir/newfile + => creates A', With newdir/newfile + + MERGE_BASE: A, Has olddir/newfile + MERGE_SIDE1: A', Has newdir/newfile + MERGE_SIDE2: B, Modifies olddir/newfile + => expected B', with threeway-merged newdir/newfile from above + + In this case, with the optimization, note that after the first commit: + * MERGE_SIDE1 remembers olddir/ -> newdir/ + * MERGE_SIDE1 has cached olddir/newfile -> newdir/newfile + Given the cached rename noted above, the second merge can proceed as + expected without needing to perform rename detection from A -> A'. + +Case 2: MERGE_SIDE1 renames old dir, MERGE_SIDE2 renames file into old dir + + This case looks like this: + MERGE_BASE: E oldfile, olddir/ + MERGE_SIDE1: G oldfile, olddir/ -> newdir/ + MERGE_SIDE2: A oldfile -> olddir/newfile + => creates A', With newdir/newfile representing original oldfile + + MERGE_BASE: A olddir/newfile + MERGE_SIDE1: A' newdir/newfile + MERGE_SIDE2: B modify olddir/newfile + => expected B', with threeway-merged newdir/newfile from above + + In this case, with the optimization, note that after the first commit: + * MERGE_SIDE1 remembers olddir/ -> newdir/ + * MERGE_SIDE1 has cached olddir/newfile -> newdir/newfile + (NOT oldfile -> newdir/newfile; compare to case with + (p->status == 'R' && new_path) in possibly_cache_new_pair()) + + Given the cached rename noted above, the second merge can proceed as + expected without needing to perform rename detection from A -> A'. + +Case 3: MERGE_SIDE1 adds new file to old dir, MERGE_SIDE2 renames old dir + + This case looks like this: + + MERGE_BASE: E, Has olddir/ + MERGE_SIDE1: G, Adds olddir/newfile + MERGE_SIDE2: A, Renames olddir/ -> newdir/ + => creates A', With newdir/newfile + + MERGE_BASE: A, Has newdir/, but no notion of newdir/newfile + MERGE_SIDE1: A', Has newdir/newfile + MERGE_SIDE2: B, Has newdir/, but no notion of newdir/newfile + => expected B', with newdir/newfile from A' + + In this case, with the optimization, note that after the first commit there + were no renames on MERGE_SIDE1, and any renames on MERGE_SIDE2 are tossed. + But the second merge didn't need any renames so this is fine. + +Case 4: MERGE_SIDE1 renames file into old dir, MERGE_SIDE2 renames old dir + + This case looks like this: + + MERGE_BASE: E, Has olddir/ + MERGE_SIDE1: G, Renames oldfile -> olddir/newfile + MERGE_SIDE2: A, Renames olddir/ -> newdir/ + => creates A', With newdir/newfile representing original oldfile + + MERGE_BASE: A, Has oldfile + MERGE_SIDE1: A', Has newdir/newfile + MERGE_SIDE2: B, Modifies oldfile + => expected B', with threeway-merged newdir/newfile from above + + In this case, with the optimization, note that after the first commit: + * MERGE_SIDE1 remembers oldfile -> newdir/newfile + (NOT oldfile -> olddir/newfile; compare to case of second + block under p->status == 'R' in possibly_cache_new_pair()) + * MERGE_SIDE2 renames are tossed because only MERGE_SIDE1 is remembered + + Given the cached rename noted above, the second merge can proceed as + expected without needing to perform rename detection from A -> A'. + +Finally, I'll just note here that interactions with the +skip-irrelevant-renames optimization means we sometimes don't detect +renames for any files within a directory that was renamed, in which +case we will not have been able to detect any rename for the directory +itself. In such a case, we do not know whether the directory was +renamed; we want to be careful to avoid cacheing some kind of "this +directory was not renamed" statement. If we did, then a subsequent +commit being rebased could add a file to the old directory, and the +user would expect it to end up in the correct directory -- something +our erroneous "this directory was not renamed" cache would preclude. diff --git a/Documentation/technical/rerere.txt b/Documentation/technical/rerere.txt index aa22d7ace8..af5f9fc24f 100644 --- a/Documentation/technical/rerere.txt +++ b/Documentation/technical/rerere.txt @@ -117,7 +117,7 @@ early A became C or B, a late X became Y or Z". We can see there are 4 combinations of ("B or C", "C or B") x ("X or Y", "Y or X"). By sorting, the conflict is given its canonical name, namely, "an -early part became B or C, a late part becames X or Y", and whenever +early part became B or C, a late part became X or Y", and whenever any of these four patterns appear, and we can get to the same conflict and resolution that we saw earlier. diff --git a/Documentation/technical/shallow.txt b/Documentation/technical/shallow.txt index 01dedfe9ff..f3738baa0f 100644 --- a/Documentation/technical/shallow.txt +++ b/Documentation/technical/shallow.txt @@ -13,7 +13,7 @@ pretend as if they are root commits (e.g. "git log" traversal stops after showing them; "git fsck" does not complain saying the commits listed on their "parent" lines do not exist). -Each line contains exactly one SHA-1. When read, a commit_graft +Each line contains exactly one object name. When read, a commit_graft will be constructed, which has nr_parent < 0 to make it easier to discern from user provided grafts. diff --git a/Documentation/technical/sparse-index.txt b/Documentation/technical/sparse-index.txt new file mode 100644 index 0000000000..3b24c1a219 --- /dev/null +++ b/Documentation/technical/sparse-index.txt @@ -0,0 +1,208 @@ +Git Sparse-Index Design Document +================================ + +The sparse-checkout feature allows users to focus a working directory on +a subset of the files at HEAD. The cone mode patterns, enabled by +`core.sparseCheckoutCone`, allow for very fast pattern matching to +discover which files at HEAD belong in the sparse-checkout cone. + +Three important scale dimensions for a Git working directory are: + +* `HEAD`: How many files are present at `HEAD`? + +* Populated: How many files are within the sparse-checkout cone. + +* Modified: How many files has the user modified in the working directory? + +We will use big-O notation -- O(X) -- to denote how expensive certain +operations are in terms of these dimensions. + +These dimensions are ordered by their magnitude: users (typically) modify +fewer files than are populated, and we can only populate files at `HEAD`. + +Problems occur if there is an extreme imbalance in these dimensions. For +example, if `HEAD` contains millions of paths but the populated set has +only tens of thousands, then commands like `git status` and `git add` can +be dominated by operations that require O(`HEAD`) operations instead of +O(Populated). Primarily, the cost is in parsing and rewriting the index, +which is filled primarily with files at `HEAD` that are marked with the +`SKIP_WORKTREE` bit. + +The sparse-index intends to take these commands that read and modify the +index from O(`HEAD`) to O(Populated). To do this, we need to modify the +index format in a significant way: add "sparse directory" entries. + +With cone mode patterns, it is possible to detect when an entire +directory will have its contents outside of the sparse-checkout definition. +Instead of listing all of the files it contains as individual entries, a +sparse-index contains an entry with the directory name, referencing the +object ID of the tree at `HEAD` and marked with the `SKIP_WORKTREE` bit. +If we need to discover the details for paths within that directory, we +can parse trees to find that list. + +At time of writing, sparse-directory entries violate expectations about the +index format and its in-memory data structure. There are many consumers in +the codebase that expect to iterate through all of the index entries and +see only files. In fact, these loops expect to see a reference to every +staged file. One way to handle this is to parse trees to replace a +sparse-directory entry with all of the files within that tree as the index +is loaded. However, parsing trees is slower than parsing the index format, +so that is a slower operation than if we left the index alone. The plan is +to make all of these integrations "sparse aware" so this expansion through +tree parsing is unnecessary and they use fewer resources than when using a +full index. + +The implementation plan below follows four phases to slowly integrate with +the sparse-index. The intention is to incrementally update Git commands to +interact safely with the sparse-index without significant slowdowns. This +may not always be possible, but the hope is that the primary commands that +users need in their daily work are dramatically improved. + +Phase I: Format and initial speedups +------------------------------------ + +During this phase, Git learns to enable the sparse-index and safely parse +one. Protections are put in place so that every consumer of the in-memory +data structure can operate with its current assumption of every file at +`HEAD`. + +At first, every index parse will call a helper method, +`ensure_full_index()`, which scans the index for sparse-directory entries +(pointing to trees) and replaces them with the full list of paths (with +blob contents) by parsing tree objects. This will be slower in all cases. +The only noticeable change in behavior will be that the serialized index +file contains sparse-directory entries. + +To start, we use a new required index extension, `sdir`, to allow +inserting sparse-directory entries into indexes with file format +versions 2, 3, and 4. This prevents Git versions that do not understand +the sparse-index from operating on one, while allowing tools that do not +understand the sparse-index to operate on repositories as long as they do +not interact with the index. A new format, index v5, will be introduced +that includes sparse-directory entries by default. It might also +introduce other features that have been considered for improving the +index, as well. + +Next, consumers of the index will be guarded against operating on a +sparse-index by inserting calls to `ensure_full_index()` or +`expand_index_to_path()`. If a specific path is requested, then those will +be protected from within the `index_file_exists()` and `index_name_pos()` +API calls: they will call `ensure_full_index()` if necessary. The +intention here is to preserve existing behavior when interacting with a +sparse-checkout. We don't want a change to happen by accident, without +tests. Many of these locations may not need any change before removing the +guards, but we should not do so without tests to ensure the expected +behavior happens. + +It may be desirable to _change_ the behavior of some commands in the +presence of a sparse index or more generally in any sparse-checkout +scenario. In such cases, these should be carefully communicated and +tested. No such behavior changes are intended during this phase. + +During a scan of the codebase, not every iteration of the cache entries +needs an `ensure_full_index()` check. The basic reasons include: + +1. The loop is scanning for entries with non-zero stage. These entries + are not collapsed into a sparse-directory entry. + +2. The loop is scanning for submodules. These entries are not collapsed + into a sparse-directory entry. + +3. The loop is part of the index API, especially around reading or + writing the format. + +4. The loop is checking for correct order of cache entries and that is + correct if and only if the sparse-directory entries are in the correct + location. + +5. The loop ignores entries with the `SKIP_WORKTREE` bit set, or is + otherwise already aware of sparse directory entries. + +6. The sparse-index is disabled at this point when using the split-index + feature, so no effort is made to protect the split-index API. + +Even after inserting these guards, we will keep expanding sparse-indexes +for most Git commands using the `command_requires_full_index` repository +setting. This setting will be on by default and disabled one builtin at a +time until we have sufficient confidence that all of the index operations +are properly guarded. + +To complete this phase, the commands `git status` and `git add` will be +integrated with the sparse-index so that they operate with O(Populated) +performance. They will be carefully tested for operations within and +outside the sparse-checkout definition. + +Phase II: Careful integrations +------------------------------ + +This phase focuses on ensuring that all index extensions and APIs work +well with a sparse-index. This requires significant increases to our test +coverage, especially for operations that interact with the working +directory outside of the sparse-checkout definition. Some of these +behaviors may not be the desirable ones, such as some tests already +marked for failure in `t1092-sparse-checkout-compatibility.sh`. + +The index extensions that may require special integrations are: + +* FS Monitor +* Untracked cache + +While integrating with these features, we should look for patterns that +might lead to better APIs for interacting with the index. Coalescing +common usage patterns into an API call can reduce the number of places +where sparse-directories need to be handled carefully. + +Phase III: Important command speedups +------------------------------------- + +At this point, the patterns for testing and implementing sparse-directory +logic should be relatively stable. This phase focuses on updating some of +the most common builtins that use the index to operate as O(Populated). +Here is a potential list of commands that could be valuable to integrate +at this point: + +* `git commit` +* `git checkout` +* `git merge` +* `git rebase` + +Hopefully, commands such as `git merge` and `git rebase` can benefit +instead from merge algorithms that do not use the index as a data +structure, such as the merge-ORT strategy. As these topics mature, we +may enable the ORT strategy by default for repositories using the +sparse-index feature. + +Along with `git status` and `git add`, these commands cover the majority +of users' interactions with the working directory. In addition, we can +integrate with these commands: + +* `git grep` +* `git rm` + +These have been proposed as some whose behavior could change when in a +repo with a sparse-checkout definition. It would be good to include this +behavior automatically when using a sparse-index. Some clarity is needed +to make the behavior switch clear to the user. + +This phase is the first where parallel work might be possible without too +much conflicts between topics. + +Phase IV: The long tail +----------------------- + +This last phase is less a "phase" and more "the new normal" after all of +the previous work. + +To start, the `command_requires_full_index` option could be removed in +favor of expanding only when hitting an API guard. + +There are many Git commands that could use special attention to operate as +O(Populated), while some might be so rare that it is acceptable to leave +them with additional overhead when a sparse-index is present. + +Here are some commands that might be useful to update: + +* `git sparse-checkout set` +* `git am` +* `git clean` +* `git stash` diff --git a/Documentation/trace2-target-values.txt b/Documentation/trace2-target-values.txt index 27d3c64e66..3985b6d3c2 100644 --- a/Documentation/trace2-target-values.txt +++ b/Documentation/trace2-target-values.txt @@ -2,7 +2,9 @@ * `0` or `false` - Disables the target. * `1` or `true` - Writes to `STDERR`. * `[2-9]` - Writes to the already opened file descriptor. -* `<absolute-pathname>` - Writes to the file in append mode. +* `<absolute-pathname>` - Writes to the file in append mode. If the target +already exists and is a directory, the traces will be written to files (one +per process) underneath the given directory. * `af_unix:[<socket_type>:]<absolute-pathname>` - Write to a Unix DomainSocket (on platforms that support them). Socket type can be either `stream` or `dgram`; if omitted Git will diff --git a/Documentation/urls.txt b/Documentation/urls.txt index bc354fe2dc..1c229d7581 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -53,6 +53,9 @@ These two syntaxes are mostly equivalent, except the former implies --local option. endif::git-clone[] +'git clone', 'git fetch' and 'git pull', but not 'git push', will also +accept a suitable bundle file. See linkgit:git-bundle[1]. + When Git doesn't know how to handle a certain transport protocol, it attempts to use the 'remote-<transport>' remote helper, if one exists. To explicitly request a remote helper, the following syntax diff --git a/Documentation/user-manual.conf b/Documentation/user-manual.conf index d87294de2f..0148f126dc 100644 --- a/Documentation/user-manual.conf +++ b/Documentation/user-manual.conf @@ -9,13 +9,3 @@ tilde=~ [linkgit-inlinemacro] <ulink url="{target}.html">{target}{0?({0})}</ulink> - -ifdef::backend-docbook[] -# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this. -[listingblock] -<example><title>{title}</title> -<literallayout class="monospaced"> -| -</literallayout> -{title#}</example> -endif::backend-docbook[] diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt index eff7890274..865074bed4 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@ -1,5 +1,7 @@ -Git User Manual -=============== += Git User Manual + +[preface] +== Introduction Git is a fast distributed revision control system. @@ -41,12 +43,10 @@ complete. [[repositories-and-branches]] -Repositories and Branches -========================= +== Repositories and Branches [[how-to-get-a-git-repository]] -How to get a Git repository ---------------------------- +=== How to get a Git repository It will be useful to have a Git repository to experiment with as you read this manual. @@ -73,8 +73,7 @@ top-level directory named `.git`, which contains all the information about the history of the project. [[how-to-check-out]] -How to check out a different version of a project -------------------------------------------------- +=== How to check out a different version of a project Git is best thought of as a tool for storing the history of a collection of files. It stores the history as a compressed collection of @@ -122,10 +121,10 @@ Tags are expected to always point at the same version of a project, while heads are expected to advance as development progresses. Create a new branch head pointing to one of these versions and check it -out using linkgit:git-checkout[1]: +out using linkgit:git-switch[1]: ------------------------------------------------ -$ git checkout -b new v2.6.13 +$ git switch -c new v2.6.13 ------------------------------------------------ The working directory then reflects the contents that the project had @@ -151,8 +150,7 @@ with no way to find the history it used to point to; so use this command carefully. [[understanding-commits]] -Understanding History: Commits ------------------------------- +=== Understanding History: Commits Every change in the history of a project is represented by a commit. The linkgit:git-show[1] command shows the most recent commit on the @@ -202,8 +200,7 @@ history, including file data and directory contents, is stored in an object with a name that is a hash of its contents. [[understanding-reachability]] -Understanding history: commits, parents, and reachability -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Understanding history: commits, parents, and reachability Every commit (except the very first commit in a project) also has a parent commit which shows what happened before this commit. @@ -227,8 +224,7 @@ that Y is a descendant of X, or that there is a chain of parents leading from commit Y to commit X. [[history-diagrams]] -Understanding history: History diagrams -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Understanding history: History diagrams We will sometimes represent Git history using diagrams like the one below. Commits are shown as "o", and the links between them with @@ -247,8 +243,7 @@ If we need to talk about a particular commit, the character "o" may be replaced with another letter or number. [[what-is-a-branch]] -Understanding history: What is a branch? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Understanding history: What is a branch? When we need to be precise, we will use the word "branch" to mean a line of development, and "branch head" (or just "head") to mean a reference @@ -261,8 +256,7 @@ However, when no confusion will result, we often just use the term "branch" both for branches and for branch heads. [[manipulating-branches]] -Manipulating branches ---------------------- +=== Manipulating branches Creating, deleting, and modifying branches is quick and easy; here's a summary of the commands: @@ -282,10 +276,10 @@ a summary of the commands: this command will fail with a warning. `git branch -D <branch>`:: delete the branch `<branch>` irrespective of its merged status. -`git checkout <branch>`:: +`git switch <branch>`:: make the current branch `<branch>`, updating the working directory to reflect the version referenced by `<branch>`. -`git checkout -b <new> <start-point>`:: +`git switch -c <new> <start-point>`:: create a new branch `<new>` referencing `<start-point>`, and check it out. @@ -299,25 +293,24 @@ ref: refs/heads/master ------------------------------------------------ [[detached-head]] -Examining an old version without creating a new branch ------------------------------------------------------- +=== Examining an old version without creating a new branch -The `git checkout` command normally expects a branch head, but will also -accept an arbitrary commit; for example, you can check out the commit -referenced by a tag: +The `git switch` command normally expects a branch head, but will also +accept an arbitrary commit when invoked with --detach; for example, +you can check out the commit referenced by a tag: ------------------------------------------------ -$ git checkout v2.6.17 +$ git switch --detach v2.6.17 Note: checking out 'v2.6.17'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this -state without impacting any branches by performing another checkout. +state without impacting any branches by performing another switch. If you want to create a new branch to retain commits you create, you may -do so (now or later) by using -b with the checkout command again. Example: +do so (now or later) by using -c with the switch command again. Example: - git checkout -b new_branch_name + git switch -c new_branch_name HEAD is now at 427abfa Linux v2.6.17 ------------------------------------------------ @@ -340,8 +333,7 @@ make up a name for the new branch. You can still create a new branch (or tag) for this version later if you decide to. [[examining-remote-branches]] -Examining branches from a remote repository -------------------------------------------- +=== Examining branches from a remote repository The "master" branch that was created at the time you cloned is a copy of the HEAD in the repository that you cloned from. That repository @@ -358,7 +350,7 @@ $ git branch -r origin/man origin/master origin/next - origin/pu + origin/seen origin/todo ------------------------------------------------ @@ -373,7 +365,7 @@ You might want to build on one of these remote-tracking branches on a branch of your own, just as you would for a tag: ------------------------------------------------ -$ git checkout -b my-todo-copy origin/todo +$ git switch -c my-todo-copy origin/todo ------------------------------------------------ You can also check out `origin/todo` directly to examine it or @@ -383,8 +375,7 @@ Note that the name "origin" is just the name that Git uses by default to refer to the repository that you cloned from. [[how-git-stores-references]] -Naming branches, tags, and other references -------------------------------------------- +=== Naming branches, tags, and other references Branches, remote-tracking branches, and tags are all references to commits. All references are named with a slash-separated path name @@ -413,8 +404,7 @@ references with the same shorthand name, see the "SPECIFYING REVISIONS" section of linkgit:gitrevisions[7]. [[Updating-a-repository-With-git-fetch]] -Updating a repository with git fetch ------------------------------------- +=== Updating a repository with git fetch After you clone a repository and commit a few changes of your own, you may wish to check the original repository for updates. @@ -425,8 +415,7 @@ repository. It will not touch any of your own branches--not even the "master" branch that was created for you on clone. [[fetching-branches]] -Fetching branches from other repositories ------------------------------------------ +=== Fetching branches from other repositories You can also track branches from repositories other than the one you cloned from, using linkgit:git-remote[1]: @@ -474,8 +463,7 @@ text editor. (See the "CONFIGURATION FILE" section of linkgit:git-config[1] for details.) [[exploring-git-history]] -Exploring Git history -===================== +== Exploring Git history Git is best thought of as a tool for storing the history of a collection of files. It does this by storing compressed snapshots of @@ -489,8 +477,7 @@ We start with one specialized tool that is useful for finding the commit that introduced a bug into a project. [[using-bisect]] -How to use bisect to find a regression --------------------------------------- +=== How to use bisect to find a regression Suppose version 2.6.18 of your project worked, but the version at "master" crashes. Sometimes the best way to find the cause of such a @@ -572,8 +559,7 @@ linkgit:git-bisect[1] for more information about this and other `git bisect` features. [[naming-commits]] -Naming commits --------------- +=== Naming commits We have seen several ways of naming commits already: @@ -637,8 +623,7 @@ e05db0fd4f31dde7005f075a84f96b360d05984b ------------------------------------------------- [[creating-tags]] -Creating tags -------------- +=== Creating tags We can also create a tag to refer to a particular commit; after running @@ -655,8 +640,7 @@ should create a tag object instead; see the linkgit:git-tag[1] man page for details. [[browsing-revisions]] -Browsing revisions ------------------- +=== Browsing revisions The linkgit:git-log[1] command can show lists of commits. On its own, it shows all commits reachable from the parent commit; but you @@ -697,8 +681,7 @@ multiple independent lines of development, the particular order that commits are listed in may be somewhat arbitrary. [[generating-diffs]] -Generating diffs ----------------- +=== Generating diffs You can generate diffs between any two versions using linkgit:git-diff[1]: @@ -726,8 +709,7 @@ will generate a file with a patch for each commit reachable from test but not from master. [[viewing-old-file-versions]] -Viewing old file versions -------------------------- +=== Viewing old file versions You can always view an old version of a file by just checking out the correct revision first. But sometimes it is more convenient to be @@ -742,12 +724,10 @@ Before the colon may be anything that names a commit, and after it may be any path to a file tracked by Git. [[history-examples]] -Examples --------- +=== Examples [[counting-commits-on-a-branch]] -Counting the number of commits on a branch -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Counting the number of commits on a branch Suppose you want to know how many commits you've made on `mybranch` since it diverged from `origin`: @@ -765,8 +745,7 @@ $ git rev-list origin..mybranch | wc -l ------------------------------------------------- [[checking-for-equal-branches]] -Check whether two branches point at the same history -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Check whether two branches point at the same history Suppose you want to check whether two branches point at the same point in history. @@ -798,8 +777,7 @@ $ git log origin...master will return no commits when the two branches are equal. [[finding-tagged-descendants]] -Find first tagged version including a given fix -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Find first tagged version including a given fix Suppose you know that the commit e05db0fd fixed a certain problem. You'd like to find the earliest tagged release that contains that @@ -883,8 +861,7 @@ shows that e05db0fd is reachable from itself, from v1.5.0-rc1, and from v1.5.0-rc2, and not from v1.5.0-rc0. [[showing-commits-unique-to-a-branch]] -Showing commits unique to a given branch -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Showing commits unique to a given branch Suppose you would like to see all the commits reachable from the branch head named `master` but not from any other head in your repository. @@ -931,8 +908,7 @@ $ gitk $( git show-ref --heads ) --not $( git show-ref --tags ) syntax such as `--not`.) [[making-a-release]] -Creating a changelog and tarball for a software release -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Creating a changelog and tarball for a software release The linkgit:git-archive[1] command can create a tar or zip archive from any version of a project; for example: @@ -983,8 +959,7 @@ and then he just cut-and-pastes the output commands after verifying that they look OK. [[Finding-commits-With-given-Content]] -Finding commits referencing a file with given content -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Finding commits referencing a file with given content Somebody hands you a copy of a file, and asks which commits modified a file such that it contained the given content either before or after the @@ -1000,12 +975,10 @@ student. The linkgit:git-log[1], linkgit:git-diff-tree[1], and linkgit:git-hash-object[1] man pages may prove helpful. [[Developing-With-git]] -Developing with Git -=================== +== Developing with Git [[telling-git-your-name]] -Telling Git your name ---------------------- +=== Telling Git your name Before creating any commits, you should introduce yourself to Git. The easiest way to do so is to use linkgit:git-config[1]: @@ -1030,8 +1003,7 @@ also edit it with your favorite editor. [[creating-a-new-repository]] -Creating a new repository -------------------------- +=== Creating a new repository Creating a new repository from scratch is very easy: @@ -1052,8 +1024,7 @@ $ git commit ------------------------------------------------- [[how-to-make-a-commit]] -How to make a commit --------------------- +=== How to make a commit Creating a new commit takes three steps: @@ -1148,8 +1119,7 @@ for inclusion in the index (by right-clicking on the diff hunk and choosing "Stage Hunk For Commit"). [[creating-good-commit-messages]] -Creating good commit messages ------------------------------ +=== Creating good commit messages Though not required, it's a good idea to begin the commit message with a single short (less than 50 character) line summarizing the @@ -1162,8 +1132,7 @@ rest of the commit in the body. [[ignoring-files]] -Ignoring files --------------- +=== Ignoring files A project will often generate files that you do 'not' want to track with Git. This typically includes files generated by a build process or temporary @@ -1205,8 +1174,7 @@ Some Git commands can also take exclude patterns directly on the command line. See linkgit:gitignore[5] for the details. [[how-to-merge]] -How to merge ------------- +=== How to merge You can rejoin two diverging branches of development using linkgit:git-merge[1]: @@ -1254,8 +1222,7 @@ has two parents, one pointing to the top of the current branch, and one to the top of the other branch. [[resolving-a-merge]] -Resolving a merge ------------------ +=== Resolving a merge When a merge isn't resolved automatically, Git leaves the index and the working tree in a special state that gives you all the @@ -1297,8 +1264,7 @@ The above is all you need to know to resolve a simple merge. But Git also provides more information to help resolve conflicts: [[conflict-resolution]] -Getting conflict-resolution help during a merge -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Getting conflict-resolution help during a merge All of the changes that Git was able to merge automatically are already added to the index file, so linkgit:git-diff[1] shows only @@ -1401,14 +1367,13 @@ the different stages of that file will be "collapsed", after which `git diff` will (by default) no longer show diffs for that file. [[undoing-a-merge]] -Undoing a merge ---------------- +=== Undoing a merge If you get stuck and decide to just give up and throw the whole mess away, you can always return to the pre-merge state with ------------------------------------------------- -$ git reset --hard HEAD +$ git merge --abort ------------------------------------------------- Or, if you've already committed the merge that you want to throw away, @@ -1423,8 +1388,7 @@ itself have been merged into another branch, as doing so may confuse further merges. [[fast-forwards]] -Fast-forward merges -------------------- +=== Fast-forward merges There is one special case not mentioned above, which is treated differently. Normally, a merge results in a merge commit, with two @@ -1438,15 +1402,14 @@ to point at the head of the merged-in branch, without any new commits being created. [[fixing-mistakes]] -Fixing mistakes ---------------- +=== Fixing mistakes If you've messed up the working tree, but haven't yet committed your mistake, you can return the entire working tree to the last committed state with ------------------------------------------------- -$ git reset --hard HEAD +$ git restore --staged --worktree :/ ------------------------------------------------- If you make a commit that you later wish you hadn't, there are two @@ -1463,8 +1426,7 @@ fundamentally different ways to fix the problem: a branch that has had its history changed. [[reverting-a-commit]] -Fixing a mistake with a new commit -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Fixing a mistake with a new commit Creating a new commit that reverts an earlier change is very easy; just pass the linkgit:git-revert[1] command a reference to the bad @@ -1490,8 +1452,7 @@ conflicts manually, just as in the case of <<resolving-a-merge, resolving a merge>>. [[fixing-a-mistake-by-rewriting-history]] -Fixing a mistake by rewriting history -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Fixing a mistake by rewriting history If the problematic commit is the most recent commit, and you have not yet made that commit public, then you may just @@ -1518,17 +1479,14 @@ this is an advanced topic to be left for <<cleaning-up-history,another chapter>>. [[checkout-of-path]] -Checking out an old version of a file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Checking out an old version of a file In the process of undoing a previous bad change, you may find it useful to check out an older version of a particular file using -linkgit:git-checkout[1]. We've used `git checkout` before to switch -branches, but it has quite different behavior if it is given a path -name: the command +linkgit:git-restore[1]. The command ------------------------------------------------- -$ git checkout HEAD^ path/to/file +$ git restore --source=HEAD^ path/to/file ------------------------------------------------- replaces path/to/file by the contents it had in the commit HEAD^, and @@ -1545,8 +1503,7 @@ $ git show HEAD^:path/to/file which will display the given version of the file. [[interrupted-work]] -Temporarily setting aside work in progress -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Temporarily setting aside work in progress While you are in the middle of working on something complicated, you find an unrelated but obvious and trivial bug. You would like to fix it @@ -1577,8 +1534,7 @@ $ git stash pop [[ensuring-good-performance]] -Ensuring good performance -------------------------- +=== Ensuring good performance On large repositories, Git depends on compression to keep the history information from taking up too much space on disk or in memory. Some @@ -1589,12 +1545,10 @@ to avoid automatic compression kicking in when it is not convenient. [[ensuring-reliability]] -Ensuring reliability --------------------- +=== Ensuring reliability [[checking-for-corruption]] -Checking the repository for corruption -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Checking the repository for corruption The linkgit:git-fsck[1] command runs a number of self-consistency checks on the repository, and reports on any problems. This may take some @@ -1620,12 +1574,10 @@ You can run `git fsck --no-dangling` to suppress these messages, and still view real errors. [[recovering-lost-changes]] -Recovering lost changes -~~~~~~~~~~~~~~~~~~~~~~~ +==== Recovering lost changes [[reflogs]] -Reflogs -^^^^^^^ +===== Reflogs Say you modify a branch with <<fixing-mistakes,`git reset --hard`>>, and then realize that the branch was the only reference you had to @@ -1672,8 +1624,7 @@ same project, the reflog history is not shared: it tells you only about how the branches in your local repository have changed over time. [[dangling-object-recovery]] -Examining dangling objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +===== Examining dangling objects In some situations the reflog may not be able to save you. For example, suppose you delete a branch, then realize you need the history it @@ -1717,12 +1668,10 @@ dangling objects can arise in other situations. [[sharing-development]] -Sharing development with others -=============================== +== Sharing development with others [[getting-updates-With-git-pull]] -Getting updates with git pull ------------------------------ +=== Getting updates with git pull After you clone a repository and commit a few changes of your own, you may wish to check the original repository for updates and merge them @@ -1785,8 +1734,7 @@ $ git merge branch are roughly equivalent. [[submitting-patches]] -Submitting patches to a project -------------------------------- +=== Submitting patches to a project If you just have a few changes, the simplest way to submit them may just be to send them as patches in email: @@ -1814,8 +1762,7 @@ Consult the mailing list for your project first to determine their requirements for submitting patches. [[importing-patches]] -Importing patches to a project ------------------------------- +=== Importing patches to a project Git also provides a tool called linkgit:git-am[1] (am stands for "apply mailbox"), for importing such an emailed series of patches. @@ -1847,8 +1794,7 @@ the original mailbox, with authorship and commit log message each taken from the message containing each patch. [[public-repositories]] -Public Git repositories ------------------------ +=== Public Git repositories Another way to submit changes to a project is to tell the maintainer of that project to pull the changes from your repository using @@ -1888,21 +1834,22 @@ pull from that repository. So the flow of changes, in a situation where there is one other developer with a public repository, looks like this: - you push - your personal repo ------------------> your public repo - ^ | - | | - | you pull | they pull - | | - | | - | they push V - their public repo <------------------- their repo +.... + you push +your personal repo ------------------> your public repo + ^ | + | | + | you pull | they pull + | | + | | + | they push V +their public repo <------------------- their repo +.... We explain how to do this in the following sections. [[setting-up-a-public-repository]] -Setting up a public repository -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Setting up a public repository Assume your personal repository is in the directory `~/proj`. We first create a new clone of the repository and tell `git daemon` that it @@ -1922,8 +1869,7 @@ public repository. You can use scp, rsync, or whatever is most convenient. [[exporting-via-git]] -Exporting a Git repository via the Git protocol -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Exporting a Git repository via the Git protocol This is the preferred method. @@ -1944,8 +1890,7 @@ linkgit:git-daemon[1] man page for details. (See especially the examples section.) [[exporting-via-http]] -Exporting a git repository via HTTP -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Exporting a git repository via HTTP The Git protocol gives better performance and reliability, but on a host with a web server set up, HTTP exports may be simpler to set up. @@ -1977,8 +1922,7 @@ for a slightly more sophisticated setup using WebDAV which also allows pushing over HTTP.) [[pushing-changes-to-a-public-repository]] -Pushing changes to a public repository -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Pushing changes to a public repository Note that the two techniques outlined above (exporting via <<exporting-via-http,http>> or <<exporting-via-git,git>>) allow other @@ -2037,8 +1981,7 @@ See the explanations of the `remote.<name>.url`, linkgit:git-config[1] for details. [[forcing-push]] -What to do when a push fails -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== What to do when a push fails If a push would not result in a <<fast-forwards,fast-forward>> of the remote branch, then it will fail with an error like: @@ -2092,8 +2035,7 @@ pull, or by a fetch followed by a rebase; see the linkgit:gitcvs-migration[7] for more. [[setting-up-a-shared-repository]] -Setting up a shared repository -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Setting up a shared repository Another way to collaborate is by using a model similar to that commonly used in CVS, where several developers with special rights @@ -2123,8 +2065,7 @@ advantages over the central shared repository: "out". [[setting-up-gitweb]] -Allowing web browsing of a repository -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Allowing web browsing of a repository The gitweb cgi script provides users an easy way to browse your project's revisions, file contents and logs without having to install @@ -2140,8 +2081,7 @@ linkgit:gitweb[1] for instructions on details setting up a permanent installation with a CGI or Perl capable server. [[how-to-get-a-git-repository-with-minimal-history]] -How to get a Git repository with minimal history ------------------------------------------------- +=== How to get a Git repository with minimal history A <<def_shallow_clone,shallow clone>>, with its truncated history, is useful when one is interested only in recent history @@ -2160,12 +2100,10 @@ have to result in huge conflicts. This limitation may make such a repository unsuitable to be used in merge based workflows. [[sharing-development-examples]] -Examples --------- +=== Examples [[maintaining-topic-branches]] -Maintaining topic branches for a Linux subsystem maintainer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Maintaining topic branches for a Linux subsystem maintainer This describes how Tony Luck uses Git in his role as maintainer of the IA64 architecture for the Linux kernel. @@ -2211,8 +2149,8 @@ $ git branch --track release origin/master These can be easily kept up to date using linkgit:git-pull[1]. ------------------------------------------------- -$ git checkout test && git pull -$ git checkout release && git pull +$ git switch test && git pull +$ git switch release && git pull ------------------------------------------------- Important note! If you have any local changes in these branches, then @@ -2264,7 +2202,7 @@ tested changes 2) help future bug hunters that use `git bisect` to find problems ------------------------------------------------- -$ git checkout -b speed-up-spinlocks v2.6.35 +$ git switch -c speed-up-spinlocks v2.6.35 ------------------------------------------------- Now you apply the patch(es), run some tests, and commit the change(s). If @@ -2279,7 +2217,7 @@ When you are happy with the state of this change, you can merge it into the "test" branch in preparation to make it public: ------------------------------------------------- -$ git checkout test && git merge speed-up-spinlocks +$ git switch test && git merge speed-up-spinlocks ------------------------------------------------- It is unlikely that you would have any conflicts here ... but you might if you @@ -2291,7 +2229,7 @@ see the value of keeping each patch (or patch series) in its own branch. It means that the patches can be moved into the `release` tree in any order. ------------------------------------------------- -$ git checkout release && git merge speed-up-spinlocks +$ git switch release && git merge speed-up-spinlocks ------------------------------------------------- After a while, you will have a number of branches, and despite the @@ -2461,8 +2399,7 @@ done [[cleaning-up-history]] -Rewriting history and maintaining patch series -============================================== +== Rewriting history and maintaining patch series Normally commits are only added to a project, never taken away or replaced. Git is designed with this assumption, and violating it will @@ -2472,8 +2409,7 @@ However, there is a situation in which it can be useful to violate this assumption. [[patch-series]] -Creating the perfect patch series ---------------------------------- +=== Creating the perfect patch series Suppose you are a contributor to a large project, and you want to add a complicated feature, and to present it to the other developers in a way @@ -2505,14 +2441,13 @@ use them, and then explain some of the problems that can arise because you are rewriting history. [[using-git-rebase]] -Keeping a patch series up to date using git rebase --------------------------------------------------- +=== Keeping a patch series up to date using git rebase Suppose that you create a branch `mywork` on a remote-tracking branch `origin`, and create some commits on top of it: ------------------------------------------------- -$ git checkout -b mywork origin +$ git switch -c mywork origin $ vi file.txt $ git commit $ vi otherfile.txt @@ -2552,7 +2487,7 @@ commits without any merges, you may instead choose to use linkgit:git-rebase[1]: ------------------------------------------------- -$ git checkout mywork +$ git switch mywork $ git rebase origin ------------------------------------------------- @@ -2593,8 +2528,7 @@ the rebase. See <<interactive-rebase>> for details, and <<reordering-patch-series>> for alternatives. [[rewriting-one-commit]] -Rewriting a single commit -------------------------- +=== Rewriting a single commit We saw in <<fixing-a-mistake-by-rewriting-history>> that you can replace the most recent commit using @@ -2612,8 +2546,7 @@ If you need to amend commits from deeper in your history, you can use <<interactive-rebase,interactive rebase's `edit` instruction>>. [[reordering-patch-series]] -Reordering or selecting from a patch series -------------------------------------------- +=== Reordering or selecting from a patch series Sometimes you want to edit a commit deeper in your history. One approach is to use `git format-patch` to create a series of patches @@ -2632,8 +2565,7 @@ $ git am *.patch ------------------------------------------------- [[interactive-rebase]] -Using interactive rebases -------------------------- +=== Using interactive rebases You can also edit a patch series with an interactive rebase. This is the same as <<reordering-patch-series,reordering a patch series using @@ -2690,16 +2622,14 @@ For a more detailed discussion of the procedure and additional tips, see the "INTERACTIVE MODE" section of linkgit:git-rebase[1]. [[patch-series-tools]] -Other tools ------------ +=== Other tools There are numerous other tools, such as StGit, which exist for the purpose of maintaining a patch series. These are outside of the scope of this manual. [[problems-With-rewriting-history]] -Problems with rewriting history -------------------------------- +=== Problems with rewriting history The primary problem with rewriting the history of a branch has to do with merging. Suppose somebody fetches your branch and merges it into @@ -2747,8 +2677,7 @@ For true distributed development that supports proper merging, published branches should never be rewritten. [[bisect-merges]] -Why bisecting merge commits can be harder than bisecting linear history ------------------------------------------------------------------------ +=== Why bisecting merge commits can be harder than bisecting linear history The linkgit:git-bisect[1] command correctly handles history that includes merge commits. However, when the commit that it finds is a @@ -2813,12 +2742,10 @@ linear by rebasing against the latest upstream version before publishing. [[advanced-branch-management]] -Advanced branch management -========================== +== Advanced branch management [[fetching-individual-branches]] -Fetching individual branches ----------------------------- +=== Fetching individual branches Instead of using linkgit:git-remote[1], you can also choose just to update one branch at a time, and to store it locally under an @@ -2846,8 +2773,7 @@ already have a branch named example-master, it will attempt to master branch. In more detail: [[fetch-fast-forwards]] -git fetch and fast-forwards ---------------------------- +=== git fetch and fast-forwards In the previous example, when updating an existing branch, `git fetch` checks to make sure that the most recent commit on the remote @@ -2866,7 +2792,7 @@ A fast-forward looks something like this: In some cases it is possible that the new head will *not* actually be a descendant of the old head. For example, the developer may have -realized she made a serious mistake, and decided to backtrack, +realized a serious mistake was made and decided to backtrack, resulting in a situation like: ................................................ @@ -2884,8 +2810,7 @@ unless you've already created a reference of your own pointing to them. [[forcing-fetch]] -Forcing git fetch to do non-fast-forward updates ------------------------------------------------- +=== Forcing git fetch to do non-fast-forward updates If git fetch fails because the new head of a branch is not a descendant of the old head, you may force the update with: @@ -2905,8 +2830,7 @@ Be aware that commits that the old version of example/master pointed at may be lost, as we saw in the previous section. [[remote-branch-configuration]] -Configuring remote-tracking branches ------------------------------------- +=== Configuring remote-tracking branches We saw above that `origin` is just a shortcut to refer to the repository that you originally cloned from. This information is @@ -2957,8 +2881,7 @@ the refspec syntax. [[git-concepts]] -Git concepts -============ +== Git concepts Git is built on a small number of simple but powerful ideas. While it is possible to get things done without understanding them, you will find @@ -2968,8 +2891,7 @@ We start with the most important, the <<def_object_database,object database>> and the <<def_index,index>>. [[the-object-database]] -The Object Database -------------------- +=== The Object Database We already saw in <<understanding-commits>> that all commits are stored @@ -3013,8 +2935,7 @@ There are four different types of objects: "blob", "tree", "commit", and The object types in some more detail: [[commit-object]] -Commit Object -~~~~~~~~~~~~~ +==== Commit Object The "commit" object links a physical state of a tree with a description of how we got there and why. Use the `--pretty=raw` option to @@ -3066,8 +2987,7 @@ commit whose parent is normally the current HEAD, and whose tree is taken from the content currently stored in the index. [[tree-object]] -Tree Object -~~~~~~~~~~~ +==== Tree Object The ever-versatile linkgit:git-show[1] command can also be used to examine tree objects, but linkgit:git-ls-tree[1] will give you more @@ -3106,8 +3026,7 @@ Note that the files all have mode 644 or 755: Git actually only pays attention to the executable bit. [[blob-object]] -Blob Object -~~~~~~~~~~~ +==== Blob Object You can use linkgit:git-show[1] to examine the contents of a blob; take, for example, the blob in the entry for `COPYING` from the tree above: @@ -3136,8 +3055,7 @@ sometimes be useful for browsing the contents of a tree that is not currently checked out. [[trust]] -Trust -~~~~~ +==== Trust If you receive the SHA-1 name of a blob from one source, and its contents from another (possibly untrusted) source, you can still trust that those @@ -3166,8 +3084,7 @@ like GPG/PGP. To assist in this, Git also provides the tag object... [[tag-object]] -Tag Object -~~~~~~~~~~ +==== Tag Object A tag object contains an object, object type, tag name, the name of the person ("tagger") who created the tag, and a message, which may contain @@ -3196,8 +3113,7 @@ objects. (Note that linkgit:git-tag[1] can also be used to create references whose names begin with `refs/tags/`). [[pack-files]] -How Git stores objects efficiently: pack files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== How Git stores objects efficiently: pack files Newly created objects are initially created in a file named after the object's SHA-1 hash (stored in `.git/objects`). @@ -3255,8 +3171,7 @@ The linkgit:git-gc[1] command performs packing, pruning, and more for you, so is normally the only high-level command you need. [[dangling-objects]] -Dangling objects -~~~~~~~~~~~~~~~~ +==== Dangling objects The linkgit:git-fsck[1] command will sometimes complain about dangling objects. They are not a problem. @@ -3275,7 +3190,7 @@ that *updated* thing--the old state that you added originally ends up not being pointed to by any commit or tree, so it's now a dangling blob object. -Similarly, when the "recursive" merge strategy runs, and finds that +Similarly, when the "ort" merge strategy runs, and finds that there are criss-cross merges and thus more than one merge base (which is fairly unusual, but it does happen), it will generate one temporary midway tree (or possibly even more, if you had lots of criss-crossing @@ -3336,8 +3251,7 @@ don't want to do that while the filesystem is mounted. accesses to a repository but you might receive confusing or scary messages.) [[recovering-from-repository-corruption]] -Recovering from repository corruption -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== Recovering from repository corruption By design, Git treats data trusted to it with caution. However, even in the absence of bugs in Git itself, it is still possible that hardware or @@ -3454,8 +3368,7 @@ whole thing. It's up to you--Git does *have* a lot of information, it is just missing one particular blob version. [[the-index]] -The index ---------- +=== The index The index is a binary file (generally kept in `.git/index`) containing a sorted list of path names, each with permissions and the SHA-1 of a blob @@ -3513,8 +3426,7 @@ If you blow the index away entirely, you generally haven't lost any information as long as you have the name of the tree that it described. [[submodules]] -Submodules -========== +== Submodules Large projects are often composed of smaller, self-contained modules. For example, an embedded Linux distribution's source tree would include every @@ -3668,13 +3580,13 @@ change within the submodule, and then update the superproject to reference the new commit: ------------------------------------------------- -$ git checkout master +$ git switch master ------------------------------------------------- or ------------------------------------------------- -$ git checkout -b fix-up +$ git switch -c fix-up ------------------------------------------------- then @@ -3700,8 +3612,8 @@ $ git push You have to run `git submodule update` after `git pull` if you want to update submodules, too. -Pitfalls with submodules ------------------------- +[[pitfalls-with-submodules]] +=== Pitfalls with submodules Always publish the submodule change before publishing the change to the superproject that references it. If you forget to publish the submodule change, @@ -3770,8 +3682,7 @@ submodule update` will not overwrite them. Instead, you get the usual warning about not being able switch from a dirty branch. [[low-level-operations]] -Low-level Git operations -======================== +== Low-level Git operations Many of the higher-level commands were originally implemented as shell scripts using a smaller core of low-level Git commands. These can still @@ -3779,8 +3690,7 @@ be useful when doing unusual things with Git, or just as a way to understand its inner workings. [[object-manipulation]] -Object access and manipulation ------------------------------- +=== Object access and manipulation The linkgit:git-cat-file[1] command can show the contents of any object, though the higher-level linkgit:git-show[1] is usually more useful. @@ -3797,11 +3707,10 @@ verified by linkgit:git-verify-tag[1], though it is normally simpler to use linkgit:git-tag[1] for both. [[the-workflow]] -The Workflow ------------- +=== The Workflow -High-level operations such as linkgit:git-commit[1], -linkgit:git-checkout[1] and linkgit:git-reset[1] work by moving data +High-level operations such as linkgit:git-commit[1] and +linkgit:git-restore[1] work by moving data between the working tree, the index, and the object database. Git provides low-level operations which perform each of these steps individually. @@ -3813,8 +3722,7 @@ the database or the working directory. Thus there are four main combinations: [[working-directory-to-index]] -working directory -> index -~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== working directory -> index The linkgit:git-update-index[1] command updates the index with information from the working directory. You generally update the @@ -3850,8 +3758,7 @@ The previously introduced linkgit:git-add[1] is just a wrapper for linkgit:git-update-index[1]. [[index-to-object-database]] -index -> object database -~~~~~~~~~~~~~~~~~~~~~~~~ +==== index -> object database You write your current index file to a "tree" object with the program @@ -3866,8 +3773,7 @@ use that tree to re-generate the index at any time by going in the other direction: [[object-database-to-index]] -object database -> index -~~~~~~~~~~~~~~~~~~~~~~~~ +==== object database -> index You read a "tree" file from the object database, and use that to populate (and overwrite--don't do this if your index contains any @@ -3883,8 +3789,7 @@ earlier. However, that is only your 'index' file: your working directory contents have not been modified. [[index-to-working-directory]] -index -> working directory -~~~~~~~~~~~~~~~~~~~~~~~~~~ +==== index -> working directory You update your working directory from the index by "checking out" files. This is not a very common operation, since normally you'd just @@ -3913,8 +3818,7 @@ Finally, there are a few odds and ends which are not purely moving from one representation to the other: [[tying-it-all-together]] -Tying it all together -~~~~~~~~~~~~~~~~~~~~~ +==== Tying it all together To commit a tree you have instantiated with `git write-tree`, you'd create a "commit" object that refers to that tree and the history @@ -3988,8 +3892,7 @@ Here is a picture that illustrates how various pieces fit together: [[examining-the-data]] -Examining the data ------------------- +=== Examining the data You can examine the data represented in the object database and the index with various helper tools. For every object, you can use @@ -4024,8 +3927,7 @@ $ git cat-file commit HEAD to see what the top commit was. [[merging-multiple-trees]] -Merging multiple trees ----------------------- +=== Merging multiple trees Git can help you perform a three-way merge, which can in turn be used for a many-way merge by repeating the merge procedure several @@ -4075,8 +3977,7 @@ index file, and you can just write the result out with [[merging-multiple-trees-2]] -Merging multiple trees, continued ---------------------------------- +=== Merging multiple trees, continued Sadly, many merges aren't trivial. If there are files that have been added, moved or removed, or if both branches have modified the @@ -4146,15 +4047,13 @@ $ git merge-index git-merge-one-file hello.c and that is what higher level `git merge -s resolve` is implemented with. [[hacking-git]] -Hacking Git -=========== +== Hacking Git This chapter covers internal details of the Git implementation which probably only Git developers need to understand. [[object-details]] -Object storage format ---------------------- +=== Object storage format All objects have a statically determined "type" which identifies the format of the object (i.e. how it is used, and how it can refer to other @@ -4184,8 +4083,7 @@ of all objects, and verifies their internal consistency (in addition to just verifying their superficial consistency through the hash). [[birdview-on-the-source-code]] -A birds-eye view of Git's source code -------------------------------------- +=== A birds-eye view of Git's source code It is not always easy for new developers to find their way through Git's source code. This section gives you a little guidance to show where to @@ -4194,7 +4092,7 @@ start. A good place to start is with the contents of the initial commit, with: ---------------------------------------------------- -$ git checkout e83c5163 +$ git switch --detach e83c5163 ---------------------------------------------------- The initial revision lays the foundation for almost everything Git has @@ -4394,25 +4292,22 @@ You see, Git is actually the best tool to find out about the source of Git itself! [[glossary]] -Git Glossary -============ +== Git Glossary [[git-explained]] -Git explained -------------- +=== Git explained include::glossary-content.txt[] [[git-quick-start]] -Appendix A: Git Quick Reference -=============================== +[appendix] +== Git Quick Reference This is a quick summary of the major commands; the previous chapters explain how these work in more detail. [[quick-creating-a-new-repository]] -Creating a new repository -------------------------- +=== Creating a new repository From a tarball: @@ -4433,14 +4328,13 @@ $ cd project ----------------------------------------------- [[managing-branches]] -Managing branches ------------------ +=== Managing branches ----------------------------------------------- -$ git branch # list all local branches in this repo -$ git checkout test # switch working directory to branch "test" -$ git branch new # create branch "new" starting at current HEAD -$ git branch -d new # delete branch "new" +$ git branch # list all local branches in this repo +$ git switch test # switch working directory to branch "test" +$ git branch new # create branch "new" starting at current HEAD +$ git branch -d new # delete branch "new" ----------------------------------------------- Instead of basing a new branch on current HEAD (the default), use: @@ -4456,7 +4350,7 @@ $ git branch new test~10 # ten commits before tip of branch "test" Create and switch to a new branch at the same time: ----------------------------------------------- -$ git checkout -b new v2.6.15 +$ git switch -c new v2.6.15 ----------------------------------------------- Update and examine branches from the repository you cloned from: @@ -4467,7 +4361,7 @@ $ git branch -r # list origin/master origin/next ... -$ git checkout -b masterwork origin/master +$ git switch -c masterwork origin/master ----------------------------------------------- Fetch a branch from a different repository, and give it a new @@ -4498,8 +4392,7 @@ $ git branch -r # list all remote branches [[exploring-history]] -Exploring history ------------------ +=== Exploring history ----------------------------------------------- $ gitk # visualize and browse history @@ -4534,8 +4427,7 @@ $ git bisect bad # if this revision is bad. ----------------------------------------------- [[making-changes]] -Making changes --------------- +=== Making changes Make sure Git knows who to blame: @@ -4565,8 +4457,7 @@ $ git commit -a # use latest content of all tracked files ----------------------------------------------- [[merging]] -Merging -------- +=== Merging ----------------------------------------------- $ git merge test # merge branch "test" into the current branch @@ -4576,8 +4467,7 @@ $ git pull . test # equivalent to git merge test ----------------------------------------------- [[sharing-your-changes]] -Sharing your changes --------------------- +=== Sharing your changes Importing or exporting patches: @@ -4622,8 +4512,7 @@ $ git push example test ----------------------------------------------- [[repository-maintenance]] -Repository maintenance ----------------------- +=== Repository maintenance Check for corruption: @@ -4639,12 +4528,11 @@ $ git gc [[todo]] -Appendix B: Notes and todo list for this manual -=============================================== +[appendix] +== Notes and todo list for this manual [[todo-list]] -Todo list ---------- +=== Todo list This is a work in progress. @@ -4689,5 +4577,5 @@ Write a chapter on using plumbing and writing scripts. Alternates, clone -reference, etc. More on recovery from repository corruption. See: - http://marc.info/?l=git&m=117263864820799&w=2 - http://marc.info/?l=git&m=117147855503798&w=2 + https://lore.kernel.org/git/Pine.LNX.4.64.0702272039540.12485@woody.linux-foundation.org/ + https://lore.kernel.org/git/Pine.LNX.4.64.0702141033400.3604@woody.linux-foundation.org/ |