diff options
120 files changed, 1311 insertions, 567 deletions
@@ -113,6 +113,7 @@ Junio C Hamano <gitster@pobox.com> <junio@pobox.com> Junio C Hamano <gitster@pobox.com> <junio@twinsun.com> Junio C Hamano <gitster@pobox.com> <junkio@cox.net> Junio C Hamano <gitster@pobox.com> <junkio@twinsun.com> +Kaartic Sivaraam <kaartic.sivaraam@gmail.com> <kaarticsivaraam91196@gmail.com> Karl Wiberg <kha@treskal.com> Karl Hasselström Karl Wiberg <kha@treskal.com> <kha@yoghurt.hemma.treskal.com> Karsten Blees <blees@dcon.de> <karsten.blees@dcon.de> diff --git a/.travis.yml b/.travis.yml index fead995edd..281f101f31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -71,7 +71,7 @@ matrix: packages: - coccinelle before_install: - # "before_script" that builds Git is inherited from base job + before_script: script: ci/run-static-analysis.sh after_failure: - env: Documentation diff --git a/Documentation/.gitignore b/Documentation/.gitignore index 2c8b2d612e..c7096f11f1 100644 --- a/Documentation/.gitignore +++ b/Documentation/.gitignore @@ -11,3 +11,4 @@ doc.dep cmds-*.txt mergetools-*.txt manpage-base-url.xsl +SubmittingPatches.txt diff --git a/Documentation/Makefile b/Documentation/Makefile index 471bb29725..2ab65561af 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -67,6 +67,7 @@ SP_ARTICLES += howto/maintain-git API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) SP_ARTICLES += $(API_DOCS) +TECH_DOCS += SubmittingPatches TECH_DOCS += technical/hash-function-transition TECH_DOCS += technical/http-protocol TECH_DOCS += technical/index-format @@ -181,6 +182,7 @@ ASCIIDOC = asciidoctor ASCIIDOC_CONF = ASCIIDOC_HTML = xhtml5 ASCIIDOC_DOCBOOK = docbook45 +ASCIIDOC_EXTRA += -acompat-mode ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;' DBLATEX_COMMON = @@ -323,6 +325,7 @@ clean: $(RM) *.pdf $(RM) howto-index.txt howto/*.html doc.dep $(RM) technical/*.html technical/api-index.txt + $(RM) SubmittingPatches.txt $(RM) $(cmds_txt) $(mergetools_txt) *.made $(RM) manpage-base-url.xsl @@ -361,6 +364,9 @@ technical/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ $(patsubst %,%.html,$(API_DOCS) technical/api-index $(TECH_DOCS)): %.html : %.txt asciidoc.conf $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt +SubmittingPatches.txt: SubmittingPatches + $(QUIET_GEN) cp $< $@ + XSLT = docbook.xsl XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css diff --git a/Documentation/RelNotes/2.15.0.txt b/Documentation/RelNotes/2.15.0.txt index 248ba70c3d..cdd761bcc2 100644 --- a/Documentation/RelNotes/2.15.0.txt +++ b/Documentation/RelNotes/2.15.0.txt @@ -65,7 +65,7 @@ UI, Workflows & Features learned to take the 'unfold' and 'only' modifiers to normalize its output, e.g. "git log --format=%(trailers:only,unfold)". - * "gitweb" shows a link to visit the 'raw' contents of blbos in the + * "gitweb" shows a link to visit the 'raw' contents of blobs in the history overview page. * "[gc] rerereResolved = 5.days" used to be invalid, as the variable @@ -109,13 +109,13 @@ Performance, Internal Implementation, Development Support etc. * Conversion from uchar[20] to struct object_id continues. * Start using selected c99 constructs in small, stable and - essentialpart of the system to catch people who care about + essential part of the system to catch people who care about older compilers that do not grok them. * The filter-process interface learned to allow a process with long latency give a "delayed" response. - * Many uses of comparision callback function the hashmap API uses + * Many uses of comparison callback function the hashmap API uses cast the callback function type when registering it to hashmap_init(), which defeats the compile time type checking when the callback interface changes (e.g. gaining more parameters). diff --git a/Documentation/RelNotes/2.15.1.txt b/Documentation/RelNotes/2.15.1.txt new file mode 100644 index 0000000000..ec06704e63 --- /dev/null +++ b/Documentation/RelNotes/2.15.1.txt @@ -0,0 +1,88 @@ +Git v2.15.1 Release Notes +========================= + +Fixes since v2.15 +----------------- + + * TravisCI build updates. + + * "auto" as a value for the columnar output configuration ought to + judge "is the output consumed by humans?" with the same criteria as + "auto" for coloured output configuration, i.e. either the standard + output stream is going to tty, or a pager is in use. We forgot the + latter, which has been fixed. + + * The experimental "color moved lines differently in diff output" + feature was buggy around "ignore whitespace changes" edges, which + has been corrected. + + * Instead of using custom line comparison and hashing functions to + implement "moved lines" coloring in the diff output, use the pair + of these functions from lower-layer xdiff/ code. + + * Some codepaths did not check for errors when asking what branch the + HEAD points at, which have been fixed. + + * "git commit", after making a commit, did not check for errors when + asking on what branch it made the commit, which has been corrected. + + * "git status --ignored -u" did not stop at a working tree of a + separate project that is embedded in an ignored directory and + listed files in that other project, instead of just showing the + directory itself as ignored. + + * A broken access to object databases in recent update to "git grep + --recurse-submodules" has been fixed. + + * A recent regression in "git rebase -i" that broke execution of git + commands from subdirectories via "exec" instruction has been fixed. + + * "git check-ref-format --branch @{-1}" bit a "BUG()" when run + outside a repository for obvious reasons; clarify the documentation + and make sure we do not even try to expand the at-mark magic in + such a case, but still call the validation logic for branch names. + + * Command line completion (in contrib/) update. + + * Description of blame.{showroot,blankboundary,showemail,date} + configuration variables have been added to "git config --help". + + * After an error from lstat(), diff_populate_filespec() function + sometimes still went ahead and used invalid data in struct stat, + which has been fixed. + + * UNC paths are also relevant in Cygwin builds and they are now + tested just like Mingw builds. + + * Correct start-up sequence so that a repository could be placed + immediately under the root directory again (which was broken at + around Git 2.13). + + * The credential helper for libsecret (in contrib/) has been improved + to allow possibly prompting the end user to unlock secrets that are + currently locked (otherwise the secrets may not be loaded). + + * Updates from GfW project. + + * "git rebase -i" recently started misbehaving when a submodule that + is configured with 'submodule.<name>.ignore' is dirty; this has + been corrected. + + * Some error messages did not quote filenames shown in it, which have + been fixed. + + * Building with NO_LIBPCRE1_JIT did not disable it, which has been fixed. + + * We used to add an empty alternate object database to the system + that does not help anything; it has been corrected. + + * Error checking in "git imap-send" for empty response has been + improved. + + * An ancient bug in "git apply --ignore-space-change" codepath has + been fixed. + + * There was a recent semantic mismerge in the codepath to write out a + section of a configuration section, which has been corrected. + +Also contains various documentation updates and code clean-ups. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 558d465b65..3ef30922ec 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -1,40 +1,47 @@ +Submitting Patches +================== + +== Guidelines + Here are some guidelines for people who want to contribute their code to this software. -(0) Decide what to base your work on. +[[base-branch]] +=== Decide what to base your work on. In general, always base your work on the oldest branch that your change is relevant to. - - A bugfix should be based on 'maint' in general. If the bug is not - present in 'maint', base it on 'master'. For a bug that's not yet - in 'master', find the topic that introduces the regression, and - base your work on the tip of the topic. +* A bugfix should be based on `maint` in general. If the bug is not + present in `maint`, base it on `master`. For a bug that's not yet + in `master`, find the topic that introduces the regression, and + 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', - base your work on the tip of that 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`, + base your work on the tip of that topic. - - Corrections and enhancements to a topic not yet in 'master' should - be based on the tip of that topic. If the topic has not been merged - to 'next', it's alright to add a note to squash minor corrections - into the series. +* Corrections and enhancements to a topic not yet in `master` should + be based on the tip of that topic. If the topic has not been merged + to `next`, it's alright to add a note to squash minor corrections + 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 - 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. +* In the exceptional case that a new feature depends on several topics + not in `master`, start working on `next` or `pu` 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. - - Some parts of the system have dedicated maintainers with their own - repositories (see the section "Subsystems" below). Changes to - these parts should be based on their trees. +* Some parts of the system have dedicated maintainers with their own + repositories (see the section "Subsystems" below). Changes 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 +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 commit is the tip of the topic branch. -(1) Make separate commits for logically separate changes. +[[separate-commits]] +=== Make separate commits for logically separate changes. Unless your patch is really trivial, you should not be sending out a patch that was generated between your working tree and @@ -58,8 +65,9 @@ differs substantially from the prior version, are all good things to have. Make sure that you have tests for the bug you are fixing. See -t/README for guidance. +`t/README` for guidance. +[[tests]] When adding a new feature, make sure that you have new tests to show 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 @@ -84,41 +92,45 @@ turning en_UK spelling to en_US). Obvious typographical fixes are much more welcomed ("teh -> "the"), preferably submitted as independent patches separate from other documentation changes. +[[whitespace-check]] Oh, another thing. We are picky about whitespaces. Make sure your changes do not trigger errors with the sample pre-commit hook shipped -in templates/hooks--pre-commit. To help ensure this does not happen, -run "git diff --check" on your changes before you commit. +in `templates/hooks--pre-commit`. To help ensure this does not happen, +run `git diff --check` on your changes before you commit. - -(2) Describe your changes well. +[[describe-changes]] +=== Describe your changes well. The first line of the commit message should be a short description (50 -characters is the soft limit, see DISCUSSION in git-commit(1)), and -should skip the full stop. It is also conventional in most cases to +characters is the soft limit, see DISCUSSION in linkgit:git-commit[1]), +and should skip the full stop. It is also conventional in most cases to prefix the first line with "area: " where the area is a filename or identifier for the general area of the code being modified, e.g. - . doc: clarify distinction between sign-off and pgp-signing - . githooks.txt: improve the intro section +* doc: clarify distinction between sign-off and pgp-signing +* githooks.txt: improve the intro section -If in doubt which identifier to use, run "git log --no-merges" on the +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...". +[[meaningful-message]] The body should provide a meaningful commit message, which: - . explains the problem the change tries to solve, i.e. what is wrong - with the current code without the change. +. explains the problem the change tries to solve, i.e. what is wrong + with the current code without the change. - . justifies the way the change solves the problem, i.e. why the - result with the change is better. +. justifies the way the change solves the problem, i.e. why the + result with the change is better. - . alternate solutions considered but discarded, if any. +. alternate solutions considered but discarded, if any. +[[imperative-mood]] Describe your changes in imperative mood, e.g. "make xyzzy do frotz" instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy to do frotz", as if you are giving orders to the codebase to change @@ -126,36 +138,43 @@ its behavior. Try to make sure your explanation can be understood without external resources. Instead of giving a URL to a mailing list 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: - Commit f86a374 ("pack-bitmap.c: fix a memleak", 2015-03-30) - noticed that ... +.... + 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, or this invocation of `git show`: - git show -s --date=short --pretty='format:%h ("%s", %ad)' <commit> +.... + git show -s --date=short --pretty='format:%h ("%s", %ad)' <commit> +.... -(3) Generate your patch using Git tools out of your commits. +[[git-tools]] +=== Generate your patch using Git tools out of your commits. Git based diff tools generate unidiff which is the preferred format. -You do not have to be afraid to use -M option to "git diff" or -"git format-patch", if your patch involves file renames. The +You do not have to be afraid to use `-M` option to `git diff` or +`git format-patch`, if your patch involves file renames. The receiving end can handle them just fine. +[[review-patch]] Please make sure your patch does not add commented out debugging code, or include any extra files which do not relate to what your patch is trying to achieve. Make sure to review your patch after generating it, to ensure accuracy. Before -sending out, please make sure it cleanly applies to the "master" +sending out, please make sure it cleanly applies to the `master` branch head. If you are preparing a work based on "next" branch, that is fine, but please mark it as such. - -(4) Sending your patches. +[[send-patches]] +=== Sending your patches. Learn to use format-patch and send-email if possible. These commands are optimized for the workflow of sending patches, avoiding many ways @@ -184,14 +203,15 @@ lose tabs that way if you are not careful. It is a common convention to prefix your subject line with [PATCH]. This lets people easily distinguish patches from other -e-mail discussions. Use of additional markers after PATCH and -the closing bracket to mark the nature of the patch is also -encouraged. E.g. [PATCH/RFC] is often used when the patch is -not ready to be applied but it is for discussion, [PATCH v2], -[PATCH v3] etc. are often seen when you are sending an update to -what you have previously sent. - -"git format-patch" command follows the best current practice to +e-mail discussions. Use of markers in addition to PATCH within +the brackets to describe the nature of the patch is also +encouraged. E.g. [RFC PATCH] (where RFC stands for "request for +comments") is often used to indicate a patch needs further +discussion before being accepted, [PATCH v2], [PATCH v3] etc. +are often seen when you are sending an update to what you have +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, @@ -199,6 +219,10 @@ 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 message starts, you can put a "From: " line to name that person. +To change the default "[PATCH]" in the subject to "[<text>]", use +`git format-patch --subject-prefix=<text>`. As a shortcut, you +can use `--rfc` instead of `--subject-prefix="RFC PATCH"`, or +`-v <n>` instead of `--subject-prefix="PATCH v<n>"`. You often want to add additional explanation about the patch, other than the commit message itself. Place such "cover letter" @@ -208,6 +232,7 @@ an explanation of changes between each iteration can be kept in Git-notes and inserted automatically following the three-dash line via `git format-patch --notes`. +[[attachment]] Do not attach the patch as a MIME attachment, compressed or not. Do not let your e-mail client send quoted-printable. Do not let your e-mail client send format=flowed which would destroy @@ -222,6 +247,7 @@ that it will be postponed. Exception: If your mailer is mangling patches then someone may ask you to re-send them using MIME, that is OK. +[[pgp-signature]] Do not PGP sign your patch. Most likely, your maintainer or other people on the list would not have your PGP key and would not bother obtaining it anyway. Your patch is not judged by who you are; a good patch from an unknown origin @@ -230,28 +256,27 @@ origin that is done poorly or does incorrect things. If you really really really really want to do a PGP signed patch, format it as "multipart/signed", not a text/plain message -that starts with '-----BEGIN PGP SIGNED MESSAGE-----'. That is +that starts with `-----BEGIN PGP SIGNED MESSAGE-----`. That is not a text/plain, it's something else. Send your patch with "To:" set to the mailing list, with "cc:" listing people who are involved in the area you are touching (the output from -"git blame $path" and "git shortlog --no-merges $path" would help to ++git blame _$path_+ and +git shortlog {litdd}no-merges _$path_+ would help to identify them), to solicit comments and reviews. +:1: footnote:[The current maintainer: gitster@pobox.com] +:2: 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 [*1*] and "cc:" the -list [*2*] for inclusion. +patch, re-send it with "To:" set to the maintainer{1} and "cc:" the +list{2} for inclusion. -Do not forget to add trailers such as "Acked-by:", "Reviewed-by:" and -"Tested-by:" lines as necessary to credit people who helped your +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. - [Addresses] - *1* The current maintainer: gitster@pobox.com - *2* The mailing list: git@vger.kernel.org - - -(5) Certify your work by adding your "Signed-off-by: " line +[[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 @@ -263,35 +288,39 @@ the patch, which certifies that you wrote it or otherwise have the right to pass it on as a open-source patch. The rules are pretty simple: if you can certify the below D-C-O: - 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. +[[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> +.... + 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. @@ -302,85 +331,86 @@ 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: -1. "Reported-by:" is used to credit someone who found the bug that - the patch attempts to fix. -2. "Acked-by:" says that the person who is more familiar with the area - the patch attempts to modify liked the patch. -3. "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. -4. "Tested-by:" is used to indicate that the person applied the patch - and found it to have the desired effect. +. `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:". ------------------------------------------------- -Subsystems with dedicated maintainers +== 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 Pat Thoyts: - git://repo.or.cz/git-gui.git + git://repo.or.cz/git-gui.git - - gitk-git/ comes from Paul Mackerras's gitk project: +- 'gitk-git/' comes from Paul Mackerras's gitk project: - git://ozlabs.org/~paulus/gitk + git://ozlabs.org/~paulus/gitk - - po/ comes from the localization coordinator, Jiang Xin: +- 'po/' comes from the localization coordinator, Jiang Xin: https://github.com/git-l10n/git-po/ Patches to these parts should be based on their trees. ------------------------------------------------- -An ideal patch flow +[[patch-flow]] +== An ideal patch flow Here is an ideal patch flow for this project the current maintainer suggests to the contributors: - (0) You come up with an itch. You code it up. +. You come up with an itch. You code it up. - (1) Send it to the list and cc people who may need to know about - the change. +. Send it to the list and cc people who may need to know about + the change. ++ +The people who may need to know are the ones whose code you +are butchering. These people happen to be the ones who are +most likely to be knowledgeable enough to help you, but +they have no obligation to help you (i.e. you ask for help, +don't demand). +git log -p {litdd} _$area_you_are_modifying_+ would +help you find out who they are. - The people who may need to know are the ones whose code you - are butchering. These people happen to be the ones who are - most likely to be knowledgeable enough to help you, but - they have no obligation to help you (i.e. you ask for help, - don't demand). "git log -p -- $area_you_are_modifying" would - help you find out who they are. +. You get comments and suggestions for improvements. You may + even get them in a "on top of your change" patch form. - (2) You get comments and suggestions for improvements. You may - even get them in a "on top of your change" patch form. +. Polish, refine, and re-send to the list and the people who + spend their time to improve your patch. Go back to step (2). - (3) Polish, refine, and re-send to the list and the people who - spend their time to improve your patch. Go back to step (2). +. The list forms consensus that the last round of your patch is + good. Send it to the maintainer and cc the list. - (4) The list forms consensus that the last round of your patch is - good. Send it to the maintainer and cc the list. - - (5) A topic branch is created with the patch and is merged to 'next', - and cooked further and eventually graduates to 'master'. +. A topic branch is created with the patch and is merged to `next`, + 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 `pu`, in order to make it easier for people play with it without having to pick up and apply the patch to their trees themselves. ------------------------------------------------- -Know the status of your patch after submission +[[patch-status]] +== Know the status of your patch after submission * You can use Git itself to find out when your patch is merged in - master. 'git pull --rebase' will automatically skip already-applied + 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 @@ -390,8 +420,8 @@ Know the status of your patch after submission entitled "What's cooking in git.git" and "What's in git.git" giving the status of various proposed changes. --------------------------------------------------- -GitHub-Travis CI hints +[[travis]] +== GitHub-Travis CI hints 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, @@ -400,25 +430,25 @@ test build here: https://travis-ci.org/git/git/builds/120473209 Follow these steps for the initial setup: - (1) Fork https://github.com/git/git to your GitHub account. - You can find detailed instructions how to fork here: - https://help.github.com/articles/fork-a-repo/ +. Fork https://github.com/git/git to your GitHub account. + You can find detailed instructions how to fork here: + https://help.github.com/articles/fork-a-repo/ - (2) Open the Travis CI website: https://travis-ci.org +. Open the Travis CI website: https://travis-ci.org - (3) Press the "Sign in with GitHub" button. +. Press the "Sign in with GitHub" button. - (4) 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 +. 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 - (5) Open your Travis CI profile page: https://travis-ci.org/profile +. Open your Travis CI profile page: https://travis-ci.org/profile - (6) Enable Travis CI builds for your Git fork. +. Enable Travis CI builds for your Git fork. After the initial setup, Travis 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://travis-ci.org/__<Your GitHub handle>__/git/branches 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 @@ -430,17 +460,16 @@ 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. - ------------------------------------------------- -MUA specific hints +[[mua]] +== MUA specific hints Some of patches I receive or pick up from the list share common patterns of breakage. Please make sure your MUA is set up properly not to corrupt whitespaces. -See the DISCUSSION section of git-format-patch(1) for hints on +See the DISCUSSION section of linkgit:git-format-patch[1] for hints on checking your patch by mailing it to yourself and applying with -git-am(1). +linkgit:git-am[1]. While you are at it, check the resulting commit log message from a trial run of applying the patch. If what is in the resulting @@ -452,23 +481,24 @@ should come after the three-dash line that signals the end of the commit message. -Pine ----- +=== Pine (Johannes Schindelin) +.... I don't know how many people still use pine, but for those poor souls it may be good to mention that the quell-flowed-text is needed for recent versions. ... the "no-strip-whitespace-before-send" option, too. AFAIK it was introduced in 4.60. +.... (Linus Torvalds) +.... And 4.58 needs at least this. ---- diff-tree 8326dd8350be64ac7fc805f6563a1d61ad10d32c (from e886a61f76edf5410573e92e38ce22974f9c40f1) Author: Linus Torvalds <torvalds@g5.osdl.org> Date: Mon Aug 15 17:23:51 2005 -0700 @@ -490,10 +520,11 @@ diff --git a/pico/pico.c b/pico/pico.c +#endif c |= COMP_EXIT; break; - +.... (Daniel Barkalow) +.... > A patch to SubmittingPatches, MUA specific help section for > users of Pine 4.63 would be very much appreciated. @@ -503,23 +534,21 @@ that or Gentoo did it.) So you need to set the "no-strip-whitespace-before-send" option, unless the option you have is "strip-whitespace-before-send", in which case you should avoid checking it. +.... +=== Thunderbird, KMail, GMail -Thunderbird, KMail, GMail -------------------------- - -See the MUA-SPECIFIC HINTS section of git-format-patch(1). +See the MUA-SPECIFIC HINTS section of linkgit:git-format-patch[1]. -Gnus ----- +=== Gnus -'|' in the *Summary* buffer can be used to pipe the current +"|" in the `*Summary*` buffer can be used to pipe the current message to an external program, and this is a handy way to drive -"git am". However, if the message is MIME encoded, what is +`git am`. However, if the message is MIME encoded, what is piped into the program is the representation you see in your -*Article* buffer after unwrapping MIME. This is often not what +`*Article*` buffer after unwrapping MIME. This is often not what you would want for two reasons. It tends to screw up non ASCII characters (most notably in people's names), and also -whitespaces (fatal in patches). Running 'C-u g' to display the -message in raw form before using '|' to run the pipe can work +whitespaces (fatal in patches). Running "C-u g" to display the +message in raw form before using "|" to run the pipe can work this problem around. diff --git a/Documentation/config.txt b/Documentation/config.txt index 1ac0ae6adb..9593bfabaa 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -949,6 +949,23 @@ apply.whitespace:: Tells 'git apply' how to handle whitespaces, in the same way as the `--whitespace` option. See linkgit:git-apply[1]. +blame.showRoot:: + Do not treat root commits as boundaries in linkgit:git-blame[1]. + This option defaults to false. + +blame.blankBoundary:: + Show blank commit object name for boundary commits in + linkgit:git-blame[1]. This option defaults to false. + +blame.showEmail:: + Show the author email instead of author name in linkgit:git-blame[1]. + This option defaults to false. + +blame.date:: + Specifies the format used to output dates in linkgit:git-blame[1]. + If unset the iso format is used. For supported values, + see the discussion of the `--date` option at linkgit:git-log[1]. + branch.autoSetupMerge:: Tells 'git branch' and 'git checkout' to set up new branches so that linkgit:git-pull[1] will appropriately merge from the diff --git a/Documentation/diff-heuristic-options.txt b/Documentation/diff-heuristic-options.txt deleted file mode 100644 index d4f3d95505..0000000000 --- a/Documentation/diff-heuristic-options.txt +++ /dev/null @@ -1,5 +0,0 @@ ---indent-heuristic:: ---no-indent-heuristic:: - These are to help debugging and tuning experimental heuristics - (which are off by default) that shift diff hunk boundaries to - make patches easier to read. diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index a88c76741e..dd0dba5b1d 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -63,7 +63,12 @@ ifndef::git-format-patch[] Synonym for `-p --raw`. endif::git-format-patch[] -include::diff-heuristic-options.txt[] +--indent-heuristic:: + Enable the heuristic that shift diff hunk boundaries to make patches + easier to read. This is the default. + +--no-indent-heuristic:: + Disable the indent heuristic. --minimal:: Spend extra time to make sure the smallest possible diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.txt index 94be4b85e0..05fd482b74 100644 --- a/Documentation/git-annotate.txt +++ b/Documentation/git-annotate.txt @@ -23,7 +23,6 @@ familiar command name for people coming from other SCM systems. OPTIONS ------- include::blame-options.txt[] -include::diff-heuristic-options.txt[] SEE ALSO -------- diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.txt index fdc3aea30a..16323eb80e 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.txt @@ -89,8 +89,6 @@ include::blame-options.txt[] abbreviated object name, use <n>+1 digits. Note that 1 column is used for a caret to mark the boundary commit. -include::diff-heuristic-options.txt[] - THE PORCELAIN FORMAT -------------------- diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index 92777cef25..cf0a0b7df2 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -77,7 +77,14 @@ reference name expressions (see linkgit:gitrevisions[7]): . at-open-brace `@{` is used as a notation to access a reflog entry. -With the `--branch` option, it expands the ``previous branch syntax'' +With the `--branch` option, the command takes a name and checks if +it can be used as a valid branch name (e.g. when creating a new +branch). The rule `git check-ref-format --branch $name` implements +may be stricter than what `git check-ref-format refs/heads/$name` +says (e.g. a dash may appear at the beginning of a ref component, +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 branch syntax'' `@{-n}`. For example, `@{-1}` is a way to refer the last branch you were on. This option should be used by porcelains to accept this syntax anywhere a branch name is expected, so they can act as if you diff --git a/Documentation/git.txt b/Documentation/git.txt index 7a1d629ca0..463b0eb0f5 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -709,6 +709,24 @@ of clones and fetches. the background which do not want to cause lock contention with other operations on the repository. Defaults to `1`. +`GIT_REDIRECT_STDIN`:: +`GIT_REDIRECT_STDOUT`:: +`GIT_REDIRECT_STDERR`:: + Windows-only: allow redirecting the standard input/output/error + handles to paths specified by the environment variables. This is + particularly useful in multi-threaded applications where the + canonical way to pass standard handles via `CreateProcess()` is + not an option because it would require the handles to be marked + inheritable (and consequently *every* spawned process would + inherit them, possibly blocking regular Git operations). The + primary intended use case is to use named pipes for communication + (e.g. `\\.\pipe\my-git-stdin-123`). ++ +Two special values are supported: `off` will simply close the +corresponding standard handle, and if `GIT_REDIRECT_STDERR` is +`2>&1`, standard error will be redirected to the same handle as +standard output. + Discussion[[Discussion]] ------------------------ diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a9dbc3f12c..879178c550 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.15.0 +DEF_VER=v2.15.1 LF=' ' @@ -1940,7 +1940,8 @@ $(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES git.res: git.rc GIT-VERSION-FILE $(QUIET_RC)$(RC) \ - $(join -DMAJOR= -DMINOR=, $(wordlist 1,2,$(subst -, ,$(subst ., ,$(GIT_VERSION))))) \ + $(join -DMAJOR= -DMINOR= -DMICRO= -DPATCHLEVEL=, $(wordlist 1, 4, \ + $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \ -DGIT_VERSION="\\\"$(GIT_VERSION)\\\"" -i $< -o $@ # This makes sure we depend on the NO_PERL setting itself. @@ -1 +1 @@ -Documentation/RelNotes/2.15.0.txt
\ No newline at end of file +Documentation/RelNotes/2.15.1.txt
\ No newline at end of file @@ -305,52 +305,33 @@ static uint32_t hash_line(const char *cp, size_t len) static int fuzzy_matchlines(const char *s1, size_t n1, const char *s2, size_t n2) { - const char *last1 = s1 + n1 - 1; - const char *last2 = s2 + n2 - 1; - int result = 0; + const char *end1 = s1 + n1; + const char *end2 = s2 + n2; /* ignore line endings */ - while ((*last1 == '\r') || (*last1 == '\n')) - last1--; - while ((*last2 == '\r') || (*last2 == '\n')) - last2--; - - /* skip leading whitespaces, if both begin with whitespace */ - if (s1 <= last1 && s2 <= last2 && isspace(*s1) && isspace(*s2)) { - while (isspace(*s1) && (s1 <= last1)) - s1++; - while (isspace(*s2) && (s2 <= last2)) - s2++; - } - /* early return if both lines are empty */ - if ((s1 > last1) && (s2 > last2)) - return 1; - while (!result) { - result = *s1++ - *s2++; - /* - * Skip whitespace inside. We check for whitespace on - * both buffers because we don't want "a b" to match - * "ab" - */ - if (isspace(*s1) && isspace(*s2)) { - while (isspace(*s1) && s1 <= last1) + while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) + end1--; + while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) + end2--; + + while (s1 < end1 && s2 < end2) { + if (isspace(*s1)) { + /* + * Skip whitespace. We check on both buffers + * because we don't want "a b" to match "ab". + */ + if (!isspace(*s2)) + return 0; + while (s1 < end1 && isspace(*s1)) s1++; - while (isspace(*s2) && s2 <= last2) + while (s2 < end2 && isspace(*s2)) s2++; - } - /* - * If we reached the end on one side only, - * lines don't match - */ - if ( - ((s2 > last2) && (s1 <= last1)) || - ((s1 > last1) && (s2 <= last2))) + } else if (*s1++ != *s2++) return 0; - if ((s1 > last1) && (s2 > last2)) - break; } - return !result; + /* If we reached the end on one side only, lines don't match. */ + return s1 == end1 && s2 == end2; } static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag) @@ -2977,6 +2958,8 @@ static int apply_one_fragment(struct apply_state *state, newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') { old--; strbuf_setlen(&newlines, newlines.len - 1); + preimage.line_allocated[preimage.nr - 1].len--; + postimage.line_allocated[postimage.nr - 1].len--; } leading = frag->leading; @@ -226,10 +226,11 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n add_name_decoration(DECORATION_NONE, buf.buf, obj); p->item = array[i].commit; - p = p->next; + if (i < cnt - 1) + p = p->next; } - if (p) - p->next = NULL; + free_commit_list(p->next); + p->next = NULL; strbuf_release(&buf); free(array); return list; @@ -360,28 +361,29 @@ static struct commit_list *do_find_bisection(struct commit_list *list, return best_bisection_sorted(list, nr); } -struct commit_list *find_bisection(struct commit_list *list, - int *reaches, int *all, - int find_all) +void find_bisection(struct commit_list **commit_list, int *reaches, + int *all, int find_all) { int nr, on_list; - struct commit_list *p, *best, *next, *last; + struct commit_list *list, *p, *best, *next, *last; int *weights; - show_list("bisection 2 entry", 0, 0, list); + show_list("bisection 2 entry", 0, 0, *commit_list); /* * Count the number of total and tree-changing items on the * list, while reversing the list. */ - for (nr = on_list = 0, last = NULL, p = list; + for (nr = on_list = 0, last = NULL, p = *commit_list; p; p = next) { unsigned flags = p->item->object.flags; next = p->next; - if (flags & UNINTERESTING) + if (flags & UNINTERESTING) { + free(p); continue; + } p->next = last; last = p; if (!(flags & TREESAME)) @@ -397,12 +399,16 @@ struct commit_list *find_bisection(struct commit_list *list, /* Do the real work of finding bisection commit. */ best = do_find_bisection(list, nr, weights, find_all); if (best) { - if (!find_all) + if (!find_all) { + list->item = best->item; + free_commit_list(list->next); + best = list; best->next = NULL; + } *reaches = weight(best); } free(weights); - return best; + *commit_list = best; } static int register_ref(const char *refname, const struct object_id *oid, @@ -954,8 +960,7 @@ int bisect_next_all(const char *prefix, int no_checkout) bisect_common(&revs); - revs.commits = find_bisection(revs.commits, &reaches, &all, - !!skipped_revs.nr); + find_bisection(&revs.commits, &reaches, &all, !!skipped_revs.nr); revs.commits = managed_skipped(revs.commits, &tried); if (!revs.commits) { @@ -1,9 +1,15 @@ #ifndef BISECT_H #define BISECT_H -extern struct commit_list *find_bisection(struct commit_list *list, - int *reaches, int *all, - int find_all); +/* + * Find bisection. If something is found, `reaches` will be the number of + * commits that the best commit reaches. `all` will be the count of + * non-SAMETREE commits. If nothing is found, `list` will be NULL. + * Otherwise, it will be either all non-SAMETREE commits or the single + * best commit, as chosen by `find_all`. + */ +extern void find_bisection(struct commit_list **list, int *reaches, int *all, + int find_all); extern struct commit_list *filter_skipped(struct commit_list *list, struct commit_list **tried, diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index 6c40ff110b..bc67d3f0a8 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -39,12 +39,14 @@ static char *collapse_slashes(const char *refname) static int check_ref_format_branch(const char *arg) { struct strbuf sb = STRBUF_INIT; + const char *name; int nongit; setup_git_directory_gently(&nongit); - if (strbuf_check_branch_ref(&sb, arg)) + if (strbuf_check_branch_ref(&sb, arg) || + !skip_prefix(sb.buf, "refs/heads/", &name)) die("'%s' is not a valid branch name", arg); - printf("%s\n", sb.buf + 11); + printf("%s\n", name); strbuf_release(&sb); return 0; } diff --git a/builtin/commit.c b/builtin/commit.c index d75b3805ea..be370f64a9 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1492,6 +1492,8 @@ static void print_summary(const char *prefix, const struct object_id *oid, diff_setup_done(&rev.diffopt); head = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + if (!head) + die_errno(_("unable to resolve HEAD after creating commit")); if (!strcmp(head, "HEAD")) head = _("detached HEAD"); else @@ -1728,7 +1730,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) allow_fast_forward = 0; } if (allow_fast_forward) - parents = reduce_heads(parents); + reduce_heads_replace(&parents); } else { if (!reflog_msg) reflog_msg = (whence == FROM_CHERRY_PICK) diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index e99b5ddbf9..27a2361e91 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -571,7 +571,7 @@ static void find_merge_parents(struct merge_parents *result, head_commit = lookup_commit(head); if (head_commit) commit_list_insert(head_commit, &parents); - parents = reduce_heads(parents); + reduce_heads_replace(&parents); while (parents) { struct commit *cmit = pop_commit(&parents); diff --git a/builtin/grep.c b/builtin/grep.c index 2d65f27d01..5a6cfe6b45 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -431,7 +431,9 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject, * store is no longer global and instead is a member of the repository * object. */ + grep_read_lock(); add_to_alternates_memory(submodule.objectdir); + grep_read_unlock(); if (oid) { struct object *object; diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 6dbd167d3b..24f6c71935 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -9,20 +9,20 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all) { - struct commit_list *result; + struct commit_list *result, *r; result = get_merge_bases_many_dirty(rev[0], rev_nr - 1, rev + 1); if (!result) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); + for (r = result; r; r = r->next) { + printf("%s\n", oid_to_hex(&r->item->object.oid)); if (!show_all) - return 0; - result = result->next; + break; } + free_commit_list(result); return 0; } @@ -51,45 +51,47 @@ static struct commit *get_commit_reference(const char *arg) static int handle_independent(int count, const char **args) { - struct commit_list *revs = NULL; - struct commit_list *result; + struct commit_list *revs = NULL, *rev; int i; for (i = count - 1; i >= 0; i--) commit_list_insert(get_commit_reference(args[i]), &revs); - result = reduce_heads(revs); - if (!result) + reduce_heads_replace(&revs); + + if (!revs) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); - result = result->next; - } + for (rev = revs; rev; rev = rev->next) + printf("%s\n", oid_to_hex(&rev->item->object.oid)); + + free_commit_list(revs); return 0; } static int handle_octopus(int count, const char **args, int show_all) { struct commit_list *revs = NULL; - struct commit_list *result; + struct commit_list *result, *rev; int i; for (i = count - 1; i >= 0; i--) commit_list_insert(get_commit_reference(args[i]), &revs); - result = reduce_heads(get_octopus_merge_bases(revs)); + result = get_octopus_merge_bases(revs); + free_commit_list(revs); + reduce_heads_replace(&result); if (!result) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); + for (rev = result; rev; rev = rev->next) { + printf("%s\n", oid_to_hex(&rev->item->object.oid)); if (!show_all) - return 0; - result = result->next; + break; } + free_commit_list(result); return 0; } diff --git a/builtin/merge.c b/builtin/merge.c index ab5ffe85e8..fbbf2a9e5e 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -999,6 +999,7 @@ static struct commit_list *reduce_parents(struct commit *head_commit, /* Find what parents to record by checking independent ones. */ parents = reduce_heads(remoteheads); + free_commit_list(remoteheads); remoteheads = NULL; remotes = &remoteheads; diff --git a/builtin/pull.c b/builtin/pull.c index 6f772e8a22..1b4d9cd974 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -112,6 +112,8 @@ static char *opt_depth; static char *opt_unshallow; static char *opt_update_shallow; static char *opt_refmap; +static char *opt_ipv4; +static char *opt_ipv6; static struct option pull_options[] = { /* Shared options */ @@ -214,6 +216,12 @@ static struct option pull_options[] = { OPT_PASSTHRU(0, "refmap", &opt_refmap, N_("refmap"), N_("specify fetch refmap"), PARSE_OPT_NONEG), + OPT_PASSTHRU('4', "ipv4", &opt_ipv4, NULL, + N_("use IPv4 addresses only"), + PARSE_OPT_NOARG), + OPT_PASSTHRU('6', "ipv6", &opt_ipv6, NULL, + N_("use IPv6 addresses only"), + PARSE_OPT_NOARG), OPT_END() }; @@ -518,6 +526,10 @@ static int run_fetch(const char *repo, const char **refspecs) argv_array_push(&args, opt_update_shallow); if (opt_refmap) argv_array_push(&args, opt_refmap); + if (opt_ipv4) + argv_array_push(&args, opt_ipv4); + if (opt_ipv6) + argv_array_push(&args, opt_ipv6); if (repo) { argv_array_push(&args, repo); @@ -745,12 +757,15 @@ static int get_octopus_merge_base(struct object_id *merge_base, if (!is_null_oid(fork_point)) commit_list_insert(lookup_commit_reference(fork_point), &revs); - result = reduce_heads(get_octopus_merge_bases(revs)); + result = get_octopus_merge_bases(revs); free_commit_list(revs); + reduce_heads_replace(&result); + if (!result) return 1; oidcpy(merge_base, &result->item->object.oid); + free_commit_list(result); return 0; } diff --git a/builtin/remote.c b/builtin/remote.c index 4f5cac96b0..bc89623695 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -565,7 +565,7 @@ static int read_remote_branches(const char *refname, item = string_list_append(rename->remote_branches, xstrdup(refname)); symref = resolve_ref_unsafe(refname, RESOLVE_REF_READING, NULL, &flag); - if (flag & REF_ISSYMREF) + if (symref && (flag & REF_ISSYMREF)) item->util = xstrdup(symref); else item->util = NULL; diff --git a/builtin/rev-list.c b/builtin/rev-list.c index c1c74d4a79..fb1c36af6a 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -397,8 +397,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (bisect_list) { int reaches = reaches, all = all; - revs.commits = find_bisection(revs.commits, &reaches, &all, - bisect_find_all); + find_bisection(&revs.commits, &reaches, &all, bisect_find_all); if (bisect_show_vars) return show_bisect_vars(&info, reaches, all); diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index a29246af35..5bd06fe900 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -12,20 +12,18 @@ case "${TRAVIS_OS_NAME:-linux}" in linux) export GIT_TEST_HTTPD=YesPlease - mkdir --parents custom/p4 - pushd custom/p4 + mkdir --parents "$P4_PATH" + pushd "$P4_PATH" wget --quiet "$P4WHENCE/bin.linux26x86_64/p4d" wget --quiet "$P4WHENCE/bin.linux26x86_64/p4" chmod u+x p4d chmod u+x p4 - export PATH="$(pwd):$PATH" popd - mkdir --parents custom/git-lfs - pushd custom/git-lfs + mkdir --parents "$GIT_LFS_PATH" + pushd "$GIT_LFS_PATH" wget --quiet "$LFSWHENCE/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" tar --extract --gunzip --file "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" cp git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs . - export PATH="$(pwd):$PATH" popd ;; osx) diff --git a/ci/lib-travisci.sh b/ci/lib-travisci.sh index b3ed0a0dda..ac05f1f469 100755 --- a/ci/lib-travisci.sh +++ b/ci/lib-travisci.sh @@ -26,3 +26,11 @@ skip_branch_tip_with_tag () { set -e skip_branch_tip_with_tag + +case "${TRAVIS_OS_NAME:-linux}" in +linux) + P4_PATH="$(pwd)/custom/p4" + GIT_LFS_PATH="$(pwd)/custom/git-lfs" + export PATH="$GIT_LFS_PATH:$P4_PATH:$PATH" + ;; +esac @@ -224,7 +224,7 @@ int finalize_colopts(unsigned int *colopts, int stdout_is_tty) if (stdout_is_tty < 0) stdout_is_tty = isatty(1); *colopts &= ~COL_ENABLE_MASK; - if (stdout_is_tty) + if (stdout_is_tty || pager_in_use()) *colopts |= COL_ENABLED; } return 0; @@ -1090,6 +1090,13 @@ struct commit_list *reduce_heads(struct commit_list *heads) return result; } +void reduce_heads_replace(struct commit_list **heads) +{ + struct commit_list *result = reduce_heads(*heads); + free_commit_list(*heads); + *heads = result; +} + static const char gpg_sig_header[] = "gpgsig"; static const int gpg_sig_header_len = sizeof(gpg_sig_header) - 1; @@ -313,7 +313,23 @@ extern int interactive_add(int argc, const char **argv, const char *prefix, int extern int run_add_interactive(const char *revision, const char *patch_mode, const struct pathspec *pathspec); -struct commit_list *reduce_heads(struct commit_list *heads); +/* + * Takes a list of commits and returns a new list where those + * have been removed that can be reached from other commits in + * the list. It is useful for, e.g., reducing the commits + * randomly thrown at the git-merge command and removing + * redundant commits that the user shouldn't have given to it. + * + * This function destroys the STALE bit of the commit objects' + * flags. + */ +extern struct commit_list *reduce_heads(struct commit_list *heads); + +/* + * Like `reduce_heads()`, except it replaces the list. Use this + * instead of `foo = reduce_heads(foo);` to avoid memory leaks. + */ +extern void reduce_heads_replace(struct commit_list **heads); struct commit_extra_header { struct commit_extra_header *next; diff --git a/compat/mingw.c b/compat/mingw.c index 8b6fa0db44..2d44d21aca 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2139,6 +2139,62 @@ static char *wcstoutfdup_startup(char *buffer, const wchar_t *wcs, size_t len) return memcpy(malloc_startup(len), buffer, len); } +static void maybe_redirect_std_handle(const wchar_t *key, DWORD std_id, int fd, + DWORD desired_access, DWORD flags) +{ + DWORD create_flag = fd ? OPEN_ALWAYS : OPEN_EXISTING; + wchar_t buf[MAX_PATH]; + DWORD max = ARRAY_SIZE(buf); + HANDLE handle; + DWORD ret = GetEnvironmentVariableW(key, buf, max); + + if (!ret || ret >= max) + return; + + /* make sure this does not leak into child processes */ + SetEnvironmentVariableW(key, NULL); + if (!wcscmp(buf, L"off")) { + close(fd); + handle = GetStdHandle(std_id); + if (handle != INVALID_HANDLE_VALUE) + CloseHandle(handle); + return; + } + if (std_id == STD_ERROR_HANDLE && !wcscmp(buf, L"2>&1")) { + handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (handle == INVALID_HANDLE_VALUE) { + close(fd); + handle = GetStdHandle(std_id); + if (handle != INVALID_HANDLE_VALUE) + CloseHandle(handle); + } else { + int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY); + SetStdHandle(std_id, handle); + dup2(new_fd, fd); + /* do *not* close the new_fd: that would close stdout */ + } + return; + } + handle = CreateFileW(buf, desired_access, 0, NULL, create_flag, + flags, NULL); + if (handle != INVALID_HANDLE_VALUE) { + int new_fd = _open_osfhandle((intptr_t)handle, O_BINARY); + SetStdHandle(std_id, handle); + dup2(new_fd, fd); + close(new_fd); + } +} + +static void maybe_redirect_std_handles(void) +{ + maybe_redirect_std_handle(L"GIT_REDIRECT_STDIN", STD_INPUT_HANDLE, 0, + GENERIC_READ, FILE_ATTRIBUTE_NORMAL); + maybe_redirect_std_handle(L"GIT_REDIRECT_STDOUT", STD_OUTPUT_HANDLE, 1, + GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL); + maybe_redirect_std_handle(L"GIT_REDIRECT_STDERR", STD_ERROR_HANDLE, 2, + GENERIC_WRITE, FILE_FLAG_NO_BUFFERING); +} + void mingw_startup(void) { int i, maxlen, argc; @@ -2146,6 +2202,8 @@ void mingw_startup(void) wchar_t **wenv, **wargv; _startupinfo si; + maybe_redirect_std_handles(); + /* get wide char arguments and environment */ si.newmode = 0; if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0) diff --git a/compat/obstack.c b/compat/obstack.c index e276ccd7b3..4d1d95beeb 100644 --- a/compat/obstack.c +++ b/compat/obstack.c @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include <gettext.h> diff --git a/compat/obstack.h b/compat/obstack.h index ceb4bdbcdd..6bc24b7644 100644 --- a/compat/obstack.h +++ b/compat/obstack.h @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ /* Summary: diff --git a/compat/poll/poll.c b/compat/poll/poll.c index ae03b74a6f..7ed3fbbea1 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + with this program; if not, see <http://www.gnu.org/licenses/>. */ /* Tell gcc not to warn about the (nfd < 0) tests, below. */ #if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__ diff --git a/compat/poll/poll.h b/compat/poll/poll.h index b7aa59d973..cd1995292a 100644 --- a/compat/poll/poll.h +++ b/compat/poll/poll.h @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef _GL_POLL_H #define _GL_POLL_H diff --git a/compat/regex/regcomp.c b/compat/regex/regcomp.c index d8bde06f1a..51cd60baa3 100644 --- a/compat/regex/regcomp.c +++ b/compat/regex/regcomp.c @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, size_t length, reg_syntax_t syntax); diff --git a/compat/regex/regex.c b/compat/regex/regex.c index 5cb23e5d59..f3e03a9eab 100644 --- a/compat/regex/regex.c +++ b/compat/regex/regex.c @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/compat/regex/regex.h b/compat/regex/regex.h index 61c9683872..4d81358a83 100644 --- a/compat/regex/regex.h +++ b/compat/regex/regex.h @@ -18,9 +18,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _REGEX_H #define _REGEX_H 1 diff --git a/compat/regex/regex_internal.c b/compat/regex/regex_internal.c index 98342b8316..59bf151336 100644 --- a/compat/regex/regex_internal.c +++ b/compat/regex/regex_internal.c @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ static void re_string_construct_common (const char *str, int len, re_string_t *pstr, diff --git a/compat/regex/regex_internal.h b/compat/regex/regex_internal.h index 4184d7f5a6..3ee8aae59d 100644 --- a/compat/regex/regex_internal.h +++ b/compat/regex/regex_internal.h @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _REGEX_INTERNAL_H #define _REGEX_INTERNAL_H 1 diff --git a/compat/regex/regexec.c b/compat/regex/regexec.c index 6f2b48a78b..1b5d89fd5e 100644 --- a/compat/regex/regexec.c +++ b/compat/regex/regexec.c @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, int n) internal_function; @@ -2315,7 +2315,7 @@ static ssize_t write_section(int fd, const char *key) struct strbuf sb = store_create_section(key); ssize_t ret; - ret = write_in_full(fd, sb.buf, sb.len) == sb.len; + ret = write_in_full(fd, sb.buf, sb.len); strbuf_release(&sb); return ret; @@ -2811,7 +2811,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename * multiple [branch "$name"] sections. */ if (copystr.len > 0) { - if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) { + if (write_in_full(out_fd, copystr.buf, copystr.len) < 0) { ret = write_error(get_lock_file_path(lock)); goto out; } @@ -2873,7 +2873,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename * logic in the loop above. */ if (copystr.len > 0) { - if (write_in_full(out_fd, copystr.buf, copystr.len) != copystr.len) { + if (write_in_full(out_fd, copystr.buf, copystr.len) < 0) { ret = write_error(get_lock_file_path(lock)); goto out; } diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 0e16f017a4..17929b0809 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -111,8 +111,7 @@ __git () # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # The latest version of this software can be obtained here: # @@ -1205,7 +1204,7 @@ _git_branch () --color --no-color --verbose --abbrev= --no-abbrev --track --no-track --contains --no-contains --merged --no-merged --set-upstream-to= --edit-description --list - --unset-upstream --delete --move --remotes + --unset-upstream --delete --move --copy --remotes --column --no-column --sort= --points-at " ;; @@ -1250,7 +1249,8 @@ _git_checkout () --*) __gitcomp " --quiet --ours --theirs --track --no-track --merge - --conflict= --orphan --patch + --conflict= --orphan --patch --detach --ignore-skip-worktree-bits + --recurse-submodules --no-recurse-submodules " ;; *) diff --git a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c index 2a317fca44..d389bfadce 100644 --- a/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c +++ b/contrib/credential/gnome-keyring/git-credential-gnome-keyring.c @@ -13,8 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 4c56979d8a..e6598b6383 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* @@ -104,7 +103,7 @@ static int keyring_get(struct credential *c) items = secret_service_search_sync(service, SECRET_SCHEMA_COMPAT_NETWORK, attributes, - SECRET_SEARCH_LOAD_SECRETS, + SECRET_SEARCH_LOAD_SECRETS | SECRET_SEARCH_UNLOCK, NULL, &error); g_hash_table_unref(attributes); diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 006134043a..86518cd93d 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -94,6 +94,12 @@ static WCHAR *wusername, *password, *protocol, *host, *path, target[1024]; static void write_item(const char *what, LPCWSTR wbuf, int wlen) { char *buf; + + if (!wbuf || !wlen) { + printf("%s=\n", what); + return; + } + int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL, FALSE); buf = xmalloc(len); @@ -160,7 +166,7 @@ static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim) static int match_cred(const CREDENTIALW *cred) { LPCWSTR target = cred->TargetName; - if (wusername && wcscmp(wusername, cred->UserName)) + if (wusername && wcscmp(wusername, cred->UserName ? cred->UserName : L"")) return 0; return match_part(&target, L"git", L":") && @@ -183,7 +189,7 @@ static void get_credential(void) for (i = 0; i < num_creds; ++i) if (match_cred(creds[i])) { write_item("username", creds[i]->UserName, - wcslen(creds[i]->UserName)); + creds[i]->UserName ? wcslen(creds[i]->UserName) : 0); write_item("password", (LPCWSTR)creds[i]->CredentialBlob, creds[i]->CredentialBlobSize / sizeof(WCHAR)); diff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el index e671f6c1c6..510e0f7103 100644 --- a/contrib/emacs/git-blame.el +++ b/contrib/emacs/git-blame.el @@ -25,9 +25,8 @@ ;; PURPOSE. See the GNU General Public License for more details. ;; You should have received a copy of the GNU General Public -;; License along with this program; if not, write to the Free -;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -;; MA 02111-1307 USA +;; License along with this program; if not, see +;; <http://www.gnu.org/licenses/>. ;; http://www.fsf.org/copyleft/gpl.html diff --git a/contrib/emacs/git.el b/contrib/emacs/git.el index 5ffc506f6d..97919f2d73 100644 --- a/contrib/emacs/git.el +++ b/contrib/emacs/git.el @@ -15,9 +15,8 @@ ;; PURPOSE. See the GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public -;; License along with this program; if not, write to the Free -;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, -;; MA 02111-1307 USA +;; License along with this program; if not, see +;; <http://www.gnu.org/licenses/>. ;;; Commentary: diff --git a/contrib/fast-import/import-directories.perl b/contrib/fast-import/import-directories.perl index 4dec1f18e4..a16f79cfdc 100755 --- a/contrib/fast-import/import-directories.perl +++ b/contrib/fast-import/import-directories.perl @@ -14,8 +14,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# along with this program; if not, see <http://www.gnu.org/licenses/>. # # ------------------------------------------------------------------------ diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 60dec86d37..de3f81667e 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program; if not, see <http://www.gnu.org/licenses/>. """ import os, os.path, sys @@ -707,83 +707,14 @@ struct moved_entry { struct moved_entry *next_line; }; -static int next_byte(const char **cp, const char **endp, - const struct diff_options *diffopt) -{ - int retval; - - if (*cp > *endp) - return -1; - - if (isspace(**cp)) { - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) { - while (*cp < *endp && isspace(**cp)) - (*cp)++; - /* - * After skipping a couple of whitespaces, - * we still have to account for one space. - */ - return (int)' '; - } - - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) { - while (*cp < *endp && isspace(**cp)) - (*cp)++; - /* return the first non-ws character via the usual below */ - } - } - - retval = (unsigned char)(**cp); - (*cp)++; - return retval; -} - static int moved_entry_cmp(const struct diff_options *diffopt, const struct moved_entry *a, const struct moved_entry *b, const void *keydata) { - const char *ap = a->es->line, *ae = a->es->line + a->es->len; - const char *bp = b->es->line, *be = b->es->line + b->es->len; - - if (!(diffopt->xdl_opts & XDF_WHITESPACE_FLAGS)) - return a->es->len != b->es->len || memcmp(ap, bp, a->es->len); - - if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_AT_EOL)) { - while (ae > ap && isspace(*ae)) - ae--; - while (be > bp && isspace(*be)) - be--; - } - - while (1) { - int ca, cb; - ca = next_byte(&ap, &ae, diffopt); - cb = next_byte(&bp, &be, diffopt); - if (ca != cb) - return 1; - if (ca < 0) - return 0; - } -} - -static unsigned get_string_hash(struct emitted_diff_symbol *es, struct diff_options *o) -{ - if (o->xdl_opts & XDF_WHITESPACE_FLAGS) { - static struct strbuf sb = STRBUF_INIT; - const char *ap = es->line, *ae = es->line + es->len; - int c; - - strbuf_reset(&sb); - while (ae > ap && isspace(*ae)) - ae--; - while ((c = next_byte(&ap, &ae, o)) > 0) - strbuf_addch(&sb, c); - - return memhash(sb.buf, sb.len); - } else { - return memhash(es->line, es->len); - } + return !xdiff_compare_lines(a->es->line, a->es->len, + b->es->line, b->es->len, + diffopt->xdl_opts); } static struct moved_entry *prepare_entry(struct diff_options *o, @@ -792,7 +723,7 @@ static struct moved_entry *prepare_entry(struct diff_options *o, struct moved_entry *ret = xmalloc(sizeof(*ret)); struct emitted_diff_symbol *l = &o->emitted_symbols->buf[line_no]; - ret->ent.hash = get_string_hash(l, o); + ret->ent.hash = xdiff_hash_string(l->line, l->len, o->xdl_opts); ret->es = l; ret->next_line = NULL; @@ -3614,14 +3545,12 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags) int fd; if (lstat(s->path, &st) < 0) { - if (errno == ENOENT) { - err_empty: - err = -1; - empty: - s->data = (char *)""; - s->size = 0; - return err; - } + err_empty: + err = -1; + empty: + s->data = (char *)""; + s->size = 0; + return err; } s->size = xsize_t(st.st_size); if (!s->size) @@ -1392,7 +1392,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir, if (!(dir->flags & DIR_NO_GITLINKS)) { unsigned char sha1[20]; if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0) - return path_untracked; + return exclude ? path_excluded : path_untracked; } return path_recurse; } diff --git a/ewah/bitmap.c b/ewah/bitmap.c index 7103ceefbf..756bdd050e 100644 --- a/ewah/bitmap.c +++ b/ewah/bitmap.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "cache.h" #include "ewok.h" diff --git a/ewah/ewah_bitmap.c b/ewah/ewah_bitmap.c index 06c479f70a..b9fdda1d3d 100644 --- a/ewah/ewah_bitmap.c +++ b/ewah/ewah_bitmap.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include "ewok.h" diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c index f73210973f..bed1994551 100644 --- a/ewah/ewah_io.c +++ b/ewah/ewah_io.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include "ewok.h" diff --git a/ewah/ewah_rlw.c b/ewah/ewah_rlw.c index c723f1aefd..b9643b7d0f 100644 --- a/ewah/ewah_rlw.c +++ b/ewah/ewah_rlw.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include "ewok.h" diff --git a/ewah/ewok.h b/ewah/ewok.h index 269a1a8706..dc43d05b64 100644 --- a/ewah/ewok.h +++ b/ewah/ewok.h @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __EWOK_BITMAP_H__ #define __EWOK_BITMAP_H__ diff --git a/ewah/ewok_rlw.h b/ewah/ewok_rlw.h index 63efdf9698..bb3c6ff7e0 100644 --- a/ewah/ewok_rlw.h +++ b/ewah/ewok_rlw.h @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #ifndef __EWOK_RLW_H__ #define __EWOK_RLW_H__ diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 5bc21b878d..ed24aa9d2f 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -24,8 +24,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}] +along with this program; if not, see <http://www.gnu.org/licenses/>.}] ###################################################################### ## diff --git a/git-rebase--am.sh b/git-rebase--am.sh index 6e64d40d6f..14c50782e0 100644 --- a/git-rebase--am.sh +++ b/git-rebase--am.sh @@ -53,6 +53,7 @@ else git format-patch -k --stdout --full-index --cherry-pick --right-only \ --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \ + --pretty=mboxrd \ $git_format_patch_opt \ "$revisions" ${restrict_revision+^$restrict_revision} \ >"$GIT_DIR/rebased-patches" @@ -83,6 +84,7 @@ else fi git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \ + --patch-format=mboxrd \ $allow_rerere_autoupdate \ ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches" ret=$? diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 2563dc52da..437815669f 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -722,7 +722,7 @@ collapse_todo_ids() { git rebase--helper --shorten-ids } -# Add commands after a pick or after a squash/fixup serie +# Add commands after a pick or after a squash/fixup series # in the todo list. add_exec_commands () { { @@ -1,6 +1,6 @@ 1 VERSIONINFO -FILEVERSION MAJOR,MINOR,0,0 -PRODUCTVERSION MAJOR,MINOR,0,0 +FILEVERSION MAJOR,MINOR,MICRO,PATCHLEVEL +PRODUCTVERSION MAJOR,MINOR,MICRO,PATCHLEVEL BEGIN BLOCK "StringFileInfo" BEGIN @@ -387,7 +387,7 @@ static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt) if (!p->pcre1_regexp) compile_regexp_failed(p, error); - p->pcre1_extra_info = pcre_study(p->pcre1_regexp, PCRE_STUDY_JIT_COMPILE, &error); + p->pcre1_extra_info = pcre_study(p->pcre1_regexp, GIT_PCRE_STUDY_JIT_COMPILE, &error); if (!p->pcre1_extra_info && error) die("%s", error); @@ -7,11 +7,12 @@ #if PCRE_MAJOR >= 8 && PCRE_MINOR >= 32 #ifndef NO_LIBPCRE1_JIT #define GIT_PCRE1_USE_JIT +#define GIT_PCRE_STUDY_JIT_COMPILE PCRE_STUDY_JIT_COMPILE #endif #endif #endif -#ifndef PCRE_STUDY_JIT_COMPILE -#define PCRE_STUDY_JIT_COMPILE 0 +#ifndef GIT_PCRE_STUDY_JIT_COMPILE +#define GIT_PCRE_STUDY_JIT_COMPILE 0 #endif #if PCRE_MAJOR <= 8 && PCRE_MINOR < 20 typedef int pcre_jit_stack; diff --git a/imap-send.c b/imap-send.c index 8c785f3ca2..54e6a80fd6 100644 --- a/imap-send.c +++ b/imap-send.c @@ -18,8 +18,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "cache.h" @@ -684,7 +683,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb, struct imap *imap = ctx->imap; char *arg, *p; - if (*s != '[') + if (!s || *s != '[') return RESP_OK; /* no response code */ s++; if (!(p = strchr(s, ']'))) { @@ -693,6 +692,10 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb, } *p++ = 0; arg = next_arg(&s); + if (!arg) { + fprintf(stderr, "IMAP error: empty response code\n"); + return RESP_BAD; + } if (!strcmp("UIDVALIDITY", arg)) { if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg))) { fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n"); @@ -725,7 +728,8 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd) { struct imap *imap = ctx->imap; struct imap_cmd *cmdp, **pcmdp; - char *cmd, *arg, *arg1; + char *cmd; + const char *arg, *arg1; int n, resp, resp2, tag; for (;;) { @@ -733,6 +737,10 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd) return RESP_BAD; arg = next_arg(&cmd); + if (!arg) { + fprintf(stderr, "IMAP error: empty response\n"); + return RESP_BAD; + } if (*arg == '*') { arg = next_arg(&cmd); if (!arg) { @@ -807,6 +815,8 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd) if (cmdp->cb.cont || cmdp->cb.data) imap->literal_pending = 0; arg = next_arg(&cmd); + if (!arg) + arg = ""; if (!strcmp("OK", arg)) resp = DRV_OK; else { @@ -18,9 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* Written August 1989 by Mike Haertel. The author may be reached (Email) at the address mike@ai.mit.edu, @@ -17,9 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA - 02110-1301, USA. */ + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* Written August 1989 by Mike Haertel. The author may be reached (Email) at the address mike@ai.mit.edu, diff --git a/log-tree.c b/log-tree.c index cea056234d..580b3a98a0 100644 --- a/log-tree.c +++ b/log-tree.c @@ -198,7 +198,7 @@ static const struct name_decoration *current_pointed_by_HEAD(const struct name_d /* Now resolve and find the matching current branch */ branch_name = resolve_ref_unsafe("HEAD", 0, NULL, &rru_flags); - if (!(rru_flags & REF_ISSYMREF)) + if (!branch_name || !(rru_flags & REF_ISSYMREF)) return NULL; if (!starts_with(branch_name, "refs/")) diff --git a/refs/files-backend.c b/refs/files-backend.c index 8cc1e07fdb..a80d60aa06 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2605,7 +2605,23 @@ static int files_transaction_prepare(struct ref_store *ref_store, goto cleanup; } backend_data->packed_refs_locked = 1; - ret = ref_transaction_prepare(packed_transaction, err); + + if (is_packed_transaction_needed(refs->packed_ref_store, + packed_transaction)) { + ret = ref_transaction_prepare(packed_transaction, err); + } else { + /* + * We can skip rewriting the `packed-refs` + * file. But we do need to leave it locked, so + * that somebody else doesn't pack a reference + * that we are trying to delete. + */ + if (ref_transaction_abort(packed_transaction, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + backend_data->packed_transaction = NULL; + } } cleanup: diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 3279d42c5a..dab8a85d9a 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1261,6 +1261,100 @@ error: return -1; } +int is_packed_transaction_needed(struct ref_store *ref_store, + struct ref_transaction *transaction) +{ + struct packed_ref_store *refs = packed_downcast( + ref_store, + REF_STORE_READ, + "is_packed_transaction_needed"); + struct strbuf referent = STRBUF_INIT; + size_t i; + int ret; + + if (!is_lock_file_locked(&refs->lock)) + BUG("is_packed_transaction_needed() called while unlocked"); + + /* + * We're only going to bother returning false for the common, + * trivial case that references are only being deleted, their + * old values are not being checked, and the old `packed-refs` + * file doesn't contain any of those reference(s). This gives + * false positives for some other cases that could + * theoretically be optimized away: + * + * 1. It could be that the old value is being verified without + * setting a new value. In this case, we could verify the + * old value here and skip the update if it agrees. If it + * disagrees, we could either let the update go through + * (the actual commit would re-detect and report the + * problem), or come up with a way of reporting such an + * error to *our* caller. + * + * 2. It could be that a new value is being set, but that it + * is identical to the current packed value of the + * reference. + * + * Neither of these cases will come up in the current code, + * because the only caller of this function passes to it a + * transaction that only includes `delete` updates with no + * `old_id`. Even if that ever changes, false positives only + * cause an optimization to be missed; they do not affect + * correctness. + */ + + /* + * Start with the cheap checks that don't require old + * reference values to be read: + */ + for (i = 0; i < transaction->nr; i++) { + struct ref_update *update = transaction->updates[i]; + + if (update->flags & REF_HAVE_OLD) + /* Have to check the old value -> needed. */ + return 1; + + if ((update->flags & REF_HAVE_NEW) && !is_null_oid(&update->new_oid)) + /* Have to set a new value -> needed. */ + return 1; + } + + /* + * The transaction isn't checking any old values nor is it + * setting any nonzero new values, so it still might be able + * to be skipped. Now do the more expensive check: the update + * is needed if any of the updates is a delete, and the old + * `packed-refs` file contains a value for that reference. + */ + ret = 0; + for (i = 0; i < transaction->nr; i++) { + struct ref_update *update = transaction->updates[i]; + unsigned int type; + struct object_id oid; + + if (!(update->flags & REF_HAVE_NEW)) + /* + * This reference isn't being deleted -> not + * needed. + */ + continue; + + if (!refs_read_raw_ref(ref_store, update->refname, + oid.hash, &referent, &type) || + errno != ENOENT) { + /* + * We have to actually delete that reference + * -> this transaction is needed. + */ + ret = 1; + break; + } + } + + strbuf_release(&referent); + return ret; +} + struct packed_transaction_backend_data { /* True iff the transaction owns the packed-refs lock. */ int own_lock; diff --git a/refs/packed-backend.h b/refs/packed-backend.h index 61687e408a..640245d3b9 100644 --- a/refs/packed-backend.h +++ b/refs/packed-backend.h @@ -23,4 +23,13 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) void packed_refs_unlock(struct ref_store *ref_store); int packed_refs_is_locked(struct ref_store *ref_store); +/* + * Return true if `transaction` really needs to be carried out against + * the specified packed_ref_store, or false if it can be skipped + * (i.e., because it is an obvious NOOP). `ref_store` must be locked + * before calling this function. + */ +int is_packed_transaction_needed(struct ref_store *ref_store, + struct ref_transaction *transaction); + #endif /* REFS_PACKED_BACKEND_H */ diff --git a/sequencer.c b/sequencer.c index f2a10cc4f2..5e09b5d34f 100644 --- a/sequencer.c +++ b/sequencer.c @@ -438,7 +438,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next, char **xopt; static struct lock_file index_lock; - hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); + if (hold_locked_index(&index_lock, LOCK_REPORT_ON_ERROR) < 0) + return -1; read_cache(); @@ -1862,12 +1863,15 @@ static int error_failed_squash(struct commit *commit, static int do_exec(const char *command_line) { + struct argv_array child_env = ARGV_ARRAY_INIT; const char *child_argv[] = { NULL, NULL }; int dirty, status; fprintf(stderr, "Executing: %s\n", command_line); child_argv[0] = command_line; - status = run_command_v_opt(child_argv, RUN_USING_SHELL); + argv_array_pushf(&child_env, "GIT_DIR=%s", absolute_path(get_git_dir())); + status = run_command_v_opt_cd_env(child_argv, RUN_USING_SHELL, NULL, + child_env.argv); /* force re-reading of the cache */ if (discard_cache() < 0 || read_cache() < 0) @@ -1897,6 +1901,8 @@ static int do_exec(const char *command_line) status = 1; } + argv_array_clear(&child_env); + return status; } @@ -2665,6 +2671,19 @@ leave_check: return res; } +static int rewrite_file(const char *path, const char *buf, size_t len) +{ + int rc = 0; + int fd = open(path, O_WRONLY | O_TRUNC); + if (fd < 0) + return error_errno(_("could not open '%s' for writing"), path); + if (write_in_full(fd, buf, len) < 0) + rc = error_errno(_("could not write to '%s'"), path); + if (close(fd) && !rc) + rc = error_errno(_("could not close '%s'"), path); + return rc; +} + /* skip picking commits whose parents are unchanged */ int skip_unnecessary_picks(void) { @@ -2737,29 +2756,11 @@ int skip_unnecessary_picks(void) } close(fd); - fd = open(rebase_path_todo(), O_WRONLY, 0666); - if (fd < 0) { - error_errno(_("could not open '%s' for writing"), - rebase_path_todo()); - todo_list_release(&todo_list); - return -1; - } - if (write_in_full(fd, todo_list.buf.buf + offset, - todo_list.buf.len - offset) < 0) { - error_errno(_("could not write to '%s'"), - rebase_path_todo()); - close(fd); + if (rewrite_file(rebase_path_todo(), todo_list.buf.buf + offset, + todo_list.buf.len - offset) < 0) { todo_list_release(&todo_list); return -1; } - if (ftruncate(fd, todo_list.buf.len - offset) < 0) { - error_errno(_("could not truncate '%s'"), - rebase_path_todo()); - todo_list_release(&todo_list); - close(fd); - return -1; - } - close(fd); todo_list.current = i; if (is_fixup(peek_command(&todo_list, 0))) @@ -2944,15 +2945,7 @@ int rearrange_squash(void) } } - fd = open(todo_file, O_WRONLY); - if (fd < 0) - res = error_errno(_("could not open '%s'"), todo_file); - else if (write(fd, buf.buf, buf.len) < 0) - res = error_errno(_("could not write to '%s'"), todo_file); - else if (ftruncate(fd, buf.len) < 0) - res = error_errno(_("could not truncate '%s'"), - todo_file); - close(fd); + res = rewrite_file(todo_file, buf.buf, buf.len); strbuf_release(&buf); } @@ -312,7 +312,9 @@ int is_git_directory(const char *suspect) size_t len; /* Check worktree-related signatures */ - strbuf_addf(&path, "%s/HEAD", suspect); + strbuf_addstr(&path, suspect); + strbuf_complete(&path, '/'); + strbuf_addstr(&path, "HEAD"); if (validate_headref(path.buf)) goto done; diff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c index c3a2b5ad17..09c6b445b9 100644 --- a/sh-i18n--envsubst.c +++ b/sh-i18n--envsubst.c @@ -30,8 +30,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program; if not, see <http://www.gnu.org/licenses/>. */ /* closeout.c - close standard output and standard error Copyright (C) 1998-2007 Free Software Foundation, Inc. @@ -47,8 +46,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include <errno.h> #include <stdio.h> diff --git a/sha1_file.c b/sha1_file.c index 10c3a0083d..36f85455e6 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -404,6 +404,9 @@ static void link_alt_odb_entries(const char *alt, int sep, struct strbuf objdirbuf = STRBUF_INIT; struct strbuf entry = STRBUF_INIT; + if (!alt || !*alt) + return; + if (depth > 5) { error("%s: ignoring alternate object stores, nesting too deep.", relative_base); @@ -607,7 +610,6 @@ void prepare_alt_odb(void) return; alt = getenv(ALTERNATE_DB_ENVIRONMENT); - if (!alt) alt = ""; alt_odb_tail = &alt_odb_list; link_alt_odb_entries(alt, PATH_SEP, NULL, 0); diff --git a/sha1_name.c b/sha1_name.c index c7c5ab376c..603e667faa 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1331,7 +1331,10 @@ void strbuf_branchname(struct strbuf *sb, const char *name, unsigned allowed) int strbuf_check_branch_ref(struct strbuf *sb, const char *name) { - strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL); + if (startup_info->have_repository) + strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL); + else + strbuf_addstr(sb, name); if (name[0] == '-') return -1; strbuf_splice(sb, 0, 0, "refs/heads/", 11); diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 05d8c4d8af..6ec2670044 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -135,7 +135,7 @@ static int cmd_resolve_ref(struct ref_store *refs, const char **argv) ref = refs_resolve_ref_unsafe(refs, refname, resolve_flags, sha1, &flags); - printf("%s %s 0x%x\n", sha1_to_hex(sha1), ref, flags); + printf("%s %s 0x%x\n", sha1_to_hex(sha1), ref ? ref : "(null)", flags); return ref ? 0 : 1; } diff --git a/t/lib-credential.sh b/t/lib-credential.sh index d8e41f7ddd..937b831ea6 100755 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -44,6 +44,7 @@ helper_test_clean() { reject $1 https example.com user2 reject $1 http path.tld user reject $1 https timeout.tld user + reject $1 https sso.tld } reject() { @@ -250,6 +251,24 @@ helper_test() { password=pass2 EOF ' + + test_expect_success "helper ($HELPER) can store empty username" ' + check approve $HELPER <<-\EOF && + protocol=https + host=sso.tld + username= + password= + EOF + check fill $HELPER <<-\EOF + protocol=https + host=sso.tld + -- + protocol=https + host=sso.tld + username= + password= + EOF + ' } helper_test_timeout() { diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 86c1a51654..c413bff9cf 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -453,4 +453,16 @@ test_expect_success 're-init from a linked worktree' ' ) ' +test_expect_success MINGW 'redirect std handles' ' + GIT_REDIRECT_STDOUT=output.txt git rev-parse --git-dir && + test .git = "$(cat output.txt)" && + test -z "$(GIT_REDIRECT_STDOUT=off git rev-parse --git-dir)" && + test_must_fail env \ + GIT_REDIRECT_STDOUT=output.txt \ + GIT_REDIRECT_STDERR="2>&1" \ + git rev-parse --git-dir --verify refs/invalid && + printf ".git\nfatal: Needed a single revision\n" >expect && + test_cmp expect output.txt +' + test_done diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index 0790edf60d..98e4a8613b 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -144,6 +144,11 @@ test_expect_success "check-ref-format --branch @{-1}" ' refname2=$(git check-ref-format --branch @{-2}) && test "$refname2" = master' +test_expect_success 'check-ref-format --branch -naster' ' + test_must_fail git check-ref-format --branch -naster >actual && + test_must_be_empty actual +' + test_expect_success 'check-ref-format --branch from subdir' ' mkdir subdir && @@ -161,6 +166,17 @@ test_expect_success 'check-ref-format --branch from subdir' ' test "$refname" = "$sha1" ' +test_expect_success 'check-ref-format --branch @{-1} from non-repo' ' + nongit test_must_fail git check-ref-format --branch @{-1} >actual && + test_must_be_empty actual +' + +test_expect_success 'check-ref-format --branch master from non-repo' ' + echo master >expect && + nongit git check-ref-format --branch master >actual && + test_cmp expect actual +' + valid_ref_normalized() { prereq= case $1 in diff --git a/t/t1409-avoid-packing-refs.sh b/t/t1409-avoid-packing-refs.sh new file mode 100755 index 0000000000..e5cb8a252d --- /dev/null +++ b/t/t1409-avoid-packing-refs.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +test_description='avoid rewriting packed-refs unnecessarily' + +. ./test-lib.sh + +# Add an identifying mark to the packed-refs file header line. This +# shouldn't upset readers, and it should be omitted if the file is +# ever rewritten. +mark_packed_refs () { + sed -e "s/^\(#.*\)/\1 t1409 /" <.git/packed-refs >.git/packed-refs.new && + mv .git/packed-refs.new .git/packed-refs +} + +# Verify that the packed-refs file is still marked. +check_packed_refs_marked () { + grep -q '^#.* t1409 ' .git/packed-refs +} + +test_expect_success 'setup' ' + git commit --allow-empty -m "Commit A" && + A=$(git rev-parse HEAD) && + git commit --allow-empty -m "Commit B" && + B=$(git rev-parse HEAD) && + git commit --allow-empty -m "Commit C" && + C=$(git rev-parse HEAD) +' + +test_expect_success 'do not create packed-refs file gratuitously' ' + test_must_fail test -f .git/packed-refs && + git update-ref refs/heads/foo $A && + test_must_fail test -f .git/packed-refs && + git update-ref refs/heads/foo $B && + test_must_fail test -f .git/packed-refs && + git update-ref refs/heads/foo $C $B && + test_must_fail test -f .git/packed-refs && + git update-ref -d refs/heads/foo && + test_must_fail test -f .git/packed-refs +' + +test_expect_success 'check that marking the packed-refs file works' ' + git for-each-ref >expected && + git pack-refs --all && + mark_packed_refs && + check_packed_refs_marked && + git for-each-ref >actual && + test_cmp expected actual && + git pack-refs --all && + test_must_fail check_packed_refs_marked && + git for-each-ref >actual2 && + test_cmp expected actual2 +' + +test_expect_success 'leave packed-refs untouched on update of packed' ' + git update-ref refs/heads/packed-update $A && + git pack-refs --all && + mark_packed_refs && + git update-ref refs/heads/packed-update $B && + check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on checked update of packed' ' + git update-ref refs/heads/packed-checked-update $A && + git pack-refs --all && + mark_packed_refs && + git update-ref refs/heads/packed-checked-update $B $A && + check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on verify of packed' ' + git update-ref refs/heads/packed-verify $A && + git pack-refs --all && + mark_packed_refs && + echo "verify refs/heads/packed-verify $A" | git update-ref --stdin && + check_packed_refs_marked +' + +test_expect_success 'touch packed-refs on delete of packed' ' + git update-ref refs/heads/packed-delete $A && + git pack-refs --all && + mark_packed_refs && + git update-ref -d refs/heads/packed-delete && + test_must_fail check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on update of loose' ' + git pack-refs --all && + git update-ref refs/heads/loose-update $A && + mark_packed_refs && + git update-ref refs/heads/loose-update $B && + check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on checked update of loose' ' + git pack-refs --all && + git update-ref refs/heads/loose-checked-update $A && + mark_packed_refs && + git update-ref refs/heads/loose-checked-update $B $A && + check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on verify of loose' ' + git pack-refs --all && + git update-ref refs/heads/loose-verify $A && + mark_packed_refs && + echo "verify refs/heads/loose-verify $A" | git update-ref --stdin && + check_packed_refs_marked +' + +test_expect_success 'leave packed-refs untouched on delete of loose' ' + git pack-refs --all && + git update-ref refs/heads/loose-delete $A && + mark_packed_refs && + git update-ref -d refs/heads/loose-delete && + check_packed_refs_marked +' + +test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index f5fd15e559..8ac58d5ea5 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -255,4 +255,26 @@ test_expect_success 'rebase commit with an ancient timestamp' ' grep "author .* 34567 +0600$" actual ' +test_expect_success 'rebase with "From " line in commit message' ' + git checkout -b preserve-from master~1 && + cat >From_.msg <<EOF && +Somebody embedded an mbox in a commit message + +This is from so-and-so: + +From a@b Mon Sep 17 00:00:00 2001 +From: John Doe <nobody@example.com> +Date: Sat, 11 Nov 2017 00:00:00 +0000 +Subject: not this message + +something +EOF + >From_ && + git add From_ && + git commit -F From_.msg && + git rebase master && + git log -1 --pretty=format:%B >out && + test_cmp From_.msg out +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 3704dbb2ec..6a82d1ed87 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -108,6 +108,17 @@ test_expect_success 'rebase -i with the exec command runs from tree root' ' rm -fr subdir ' +test_expect_success 'rebase -i with exec allows git commands in subdirs' ' + test_when_finished "rm -rf subdir" && + test_when_finished "git rebase --abort ||:" && + git checkout master && + mkdir subdir && (cd subdir && + set_fake_editor && + FAKE_LINES="1 exec_cd_subdir_&&_git_rev-parse_--is-inside-work-tree" \ + git rebase -i HEAD^ + ) +' + test_expect_success 'rebase -i with the exec command checks tree cleanness' ' git checkout master && set_fake_editor && diff --git a/t/t3426-rebase-submodule.sh b/t/t3426-rebase-submodule.sh index ebf4f5e4b2..a2bba04ba9 100755 --- a/t/t3426-rebase-submodule.sh +++ b/t/t3426-rebase-submodule.sh @@ -40,4 +40,21 @@ git_rebase_interactive () { test_submodule_switch "git_rebase_interactive" +test_expect_success 'rebase interactive ignores modified submodules' ' + test_when_finished "rm -rf super sub" && + git init sub && + git -C sub commit --allow-empty -m "Initial commit" && + git init super && + git -C super submodule add ../sub && + git -C super config submodule.sub.ignore dirty && + >super/foo && + git -C super add foo && + git -C super commit -m "Initial commit" && + test_commit -C super a && + test_commit -C super b && + test_commit -C super/sub c && + set_fake_editor && + git -C super rebase -i HEAD^^ +' + test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index f8568f8841..ab5500db44 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -688,7 +688,7 @@ test_expect_success 'checking out a commit after submodule removal needs manual git submodule update && git checkout -q HEAD^ && git checkout -q master 2>actual && - test_i18ngrep "^warning: unable to rmdir submod:" actual && + test_i18ngrep "^warning: unable to rmdir '\''submod'\'':" actual && git status -s submod >actual && echo "?? submod/" >expected && test_cmp expected actual && diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 87083f728f..6c9a93b734 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -1318,30 +1318,38 @@ test_expect_success 'no effect from --color-moved with --word-diff' ' test_cmp expect actual ' -test_expect_success 'move detection ignoring whitespace ' ' +test_expect_success 'set up whitespace tests' ' git reset --hard && - cat <<\EOF >lines.txt && -line 1 -line 2 -line 3 -line 4 -long line 5 -long line 6 -long line 7 -EOF - git add lines.txt && - git commit -m "add poetry" && - cat <<\EOF >lines.txt && - long line 5 + # Note that these lines have no leading or trailing whitespace. + cat <<-\EOF >lines.txt && + line 1 + line 2 + line 3 + line 4 + line 5 long line 6 long line 7 -line 1 -line 2 -line 3 -line 4 -EOF - test_config color.diff.oldMoved "magenta" && - test_config color.diff.newMoved "cyan" && + long line 8 + long line 9 + EOF + git add lines.txt && + git commit -m "add poetry" && + git config color.diff.oldMoved "magenta" && + git config color.diff.newMoved "cyan" +' + +test_expect_success 'move detection ignoring whitespace ' ' + q_to_tab <<-\EOF >lines.txt && + Qlong line 6 + Qlong line 7 + Qlong line 8 + Qchanged long line 9 + line 1 + line 2 + line 3 + line 4 + line 5 + EOF git diff HEAD --no-renames --color-moved --color | grep -v "index" | test_decode_color >actual && @@ -1349,17 +1357,20 @@ EOF <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> <BOLD>+++ b/lines.txt<RESET> - <CYAN>@@ -1,7 +1,7 @@<RESET> - <GREEN>+<RESET> <GREEN>long line 5<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> <GREEN>+<RESET> <GREEN>long line 6<RESET> <GREEN>+<RESET> <GREEN>long line 7<RESET> + <GREEN>+<RESET> <GREEN>long line 8<RESET> + <GREEN>+<RESET> <GREEN>changed long line 9<RESET> line 1<RESET> line 2<RESET> line 3<RESET> line 4<RESET> - <RED>-long line 5<RESET> + line 5<RESET> <RED>-long line 6<RESET> <RED>-long line 7<RESET> + <RED>-long line 8<RESET> + <RED>-long line 9<RESET> EOF test_cmp expected actual && @@ -1370,21 +1381,160 @@ EOF <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> <BOLD>+++ b/lines.txt<RESET> - <CYAN>@@ -1,7 +1,7 @@<RESET> - <CYAN>+<RESET> <CYAN>long line 5<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> <CYAN>+<RESET> <CYAN>long line 6<RESET> <CYAN>+<RESET> <CYAN>long line 7<RESET> + <CYAN>+<RESET> <CYAN>long line 8<RESET> + <GREEN>+<RESET> <GREEN>changed long line 9<RESET> + line 1<RESET> + line 2<RESET> + line 3<RESET> + line 4<RESET> + line 5<RESET> + <MAGENTA>-long line 6<RESET> + <MAGENTA>-long line 7<RESET> + <MAGENTA>-long line 8<RESET> + <RED>-long line 9<RESET> + EOF + test_cmp expected actual +' + +test_expect_success 'move detection ignoring whitespace changes' ' + git reset --hard && + # Lines 6-8 have a space change, but 9 is new whitespace + q_to_tab <<-\EOF >lines.txt && + longQline 6 + longQline 7 + longQline 8 + long liQne 9 + line 1 + line 2 + line 3 + line 4 + line 5 + EOF + + git diff HEAD --no-renames --color-moved --color | + grep -v "index" | + test_decode_color >actual && + cat <<-\EOF >expected && + <BOLD>diff --git a/lines.txt b/lines.txt<RESET> + <BOLD>--- a/lines.txt<RESET> + <BOLD>+++ b/lines.txt<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> + <GREEN>+<RESET><GREEN>long line 6<RESET> + <GREEN>+<RESET><GREEN>long line 7<RESET> + <GREEN>+<RESET><GREEN>long line 8<RESET> + <GREEN>+<RESET><GREEN>long li ne 9<RESET> + line 1<RESET> + line 2<RESET> + line 3<RESET> + line 4<RESET> + line 5<RESET> + <RED>-long line 6<RESET> + <RED>-long line 7<RESET> + <RED>-long line 8<RESET> + <RED>-long line 9<RESET> + EOF + test_cmp expected actual && + + git diff HEAD --no-renames -b --color-moved --color | + grep -v "index" | + test_decode_color >actual && + cat <<-\EOF >expected && + <BOLD>diff --git a/lines.txt b/lines.txt<RESET> + <BOLD>--- a/lines.txt<RESET> + <BOLD>+++ b/lines.txt<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> + <CYAN>+<RESET><CYAN>long line 6<RESET> + <CYAN>+<RESET><CYAN>long line 7<RESET> + <CYAN>+<RESET><CYAN>long line 8<RESET> + <GREEN>+<RESET><GREEN>long li ne 9<RESET> + line 1<RESET> + line 2<RESET> + line 3<RESET> + line 4<RESET> + line 5<RESET> + <MAGENTA>-long line 6<RESET> + <MAGENTA>-long line 7<RESET> + <MAGENTA>-long line 8<RESET> + <RED>-long line 9<RESET> + EOF + test_cmp expected actual +' + +test_expect_success 'move detection ignoring whitespace at eol' ' + git reset --hard && + # Lines 6-9 have new eol whitespace, but 9 also has it in the middle + q_to_tab <<-\EOF >lines.txt && + long line 6Q + long line 7Q + long line 8Q + longQline 9Q + line 1 + line 2 + line 3 + line 4 + line 5 + EOF + + # avoid cluttering the output with complaints about our eol whitespace + test_config core.whitespace -blank-at-eol && + + git diff HEAD --no-renames --color-moved --color | + grep -v "index" | + test_decode_color >actual && + cat <<-\EOF >expected && + <BOLD>diff --git a/lines.txt b/lines.txt<RESET> + <BOLD>--- a/lines.txt<RESET> + <BOLD>+++ b/lines.txt<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> + <GREEN>+<RESET><GREEN>long line 6 <RESET> + <GREEN>+<RESET><GREEN>long line 7 <RESET> + <GREEN>+<RESET><GREEN>long line 8 <RESET> + <GREEN>+<RESET><GREEN>long line 9 <RESET> + line 1<RESET> + line 2<RESET> + line 3<RESET> + line 4<RESET> + line 5<RESET> + <RED>-long line 6<RESET> + <RED>-long line 7<RESET> + <RED>-long line 8<RESET> + <RED>-long line 9<RESET> + EOF + test_cmp expected actual && + + git diff HEAD --no-renames --ignore-space-at-eol --color-moved --color | + grep -v "index" | + test_decode_color >actual && + cat <<-\EOF >expected && + <BOLD>diff --git a/lines.txt b/lines.txt<RESET> + <BOLD>--- a/lines.txt<RESET> + <BOLD>+++ b/lines.txt<RESET> + <CYAN>@@ -1,9 +1,9 @@<RESET> + <CYAN>+<RESET><CYAN>long line 6 <RESET> + <CYAN>+<RESET><CYAN>long line 7 <RESET> + <CYAN>+<RESET><CYAN>long line 8 <RESET> + <GREEN>+<RESET><GREEN>long line 9 <RESET> line 1<RESET> line 2<RESET> line 3<RESET> line 4<RESET> - <MAGENTA>-long line 5<RESET> + line 5<RESET> <MAGENTA>-long line 6<RESET> <MAGENTA>-long line 7<RESET> + <MAGENTA>-long line 8<RESET> + <RED>-long line 9<RESET> EOF test_cmp expected actual ' +test_expect_success 'clean up whitespace-test colors' ' + git config --unset color.diff.oldMoved && + git config --unset color.diff.newMoved +' + test_expect_success '--color-moved block at end of diff output respects MIN_ALNUM_COUNT' ' git reset --hard && >bar && @@ -1530,13 +1680,4 @@ test_expect_success 'move detection with submodules' ' test_cmp expect decoded_actual ' -test_expect_success 'move detection with whitespace changes' ' - test_when_finished "git reset --hard" && - test_seq 10 >test && - git add test && - sed s/3/42/ <test >test.tmp && - mv test.tmp test && - git -c diff.colormoved diff --ignore-space-change -- test -' - test_done diff --git a/t/t4107-apply-ignore-whitespace.sh b/t/t4107-apply-ignore-whitespace.sh index 9e29b5262d..ac72eeaf27 100755 --- a/t/t4107-apply-ignore-whitespace.sh +++ b/t/t4107-apply-ignore-whitespace.sh @@ -178,4 +178,18 @@ test_expect_success 'patch5 fails (--no-ignore-whitespace)' ' test_must_fail git apply --no-ignore-whitespace patch5.patch ' +test_expect_success 'apply --ignore-space-change --inaccurate-eof' ' + echo 1 >file && + git apply --ignore-space-change --inaccurate-eof <<-\EOF && + diff --git a/file b/file + --- a/file + +++ b/file + @@ -1 +1 @@ + -1 + +2 + EOF + printf 2 >expect && + test_cmp expect file +' + test_done diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index 9df054bf05..da10478f59 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -9,6 +9,7 @@ test_description='git shortlog . ./test-lib.sh test_expect_success 'setup' ' + test_tick && echo 1 >a1 && git add a1 && tree=$(git write-tree) && @@ -59,7 +60,7 @@ fuzz() { file=$1 && sed " s/$_x40/OBJECT_NAME/g - s/$_x05/OBJID/g + s/$_x35/OBJID/g s/^ \{6\}[CTa].*/ SUBJECT/g s/^ \{8\}[^ ].*/ CONTINUATION/g " <"$file" >"$file.fuzzy" && @@ -81,7 +82,7 @@ test_expect_success 'pretty format' ' test_expect_success '--abbrev' ' sed s/SUBJECT/OBJID/ expect.template >expect && - git shortlog --format="%h" --abbrev=5 HEAD >log && + git shortlog --format="%h" --abbrev=35 HEAD >log && fuzz log >log.predictable && test_cmp expect log.predictable ' diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-clone-push-unc.sh index b322c2f722..ba548df4a9 100755 --- a/t/t5580-clone-push-unc.sh +++ b/t/t5580-clone-push-unc.sh @@ -3,12 +3,18 @@ test_description='various Windows-only path tests' . ./test-lib.sh -if ! test_have_prereq MINGW; then +if test_have_prereq CYGWIN +then + alias winpwd='cygpath -aw .' +elif test_have_prereq MINGW +then + alias winpwd=pwd +else skip_all='skipping Windows-only path tests' test_done fi -UNCPATH="$(pwd)" +UNCPATH="$(winpwd)" case "$UNCPATH" in [A-Z]:*) # Use administrative share e.g. \\localhost\C$\git-sdk-64\usr\src\git @@ -45,8 +51,8 @@ test_expect_success push ' test "$rev" = "$(git rev-parse --verify refs/heads/to-push)" ' -test_expect_success 'remote nick cannot contain backslashes' ' - BACKSLASHED="$(pwd | tr / \\\\)" && +test_expect_success MINGW 'remote nick cannot contain backslashes' ' + BACKSLASHED="$(winpwd | tr / \\\\)" && git ls-remote "$BACKSLASHED" >out 2>err && test_i18ngrep ! "unable to access" err ' diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 9c56f771b6..50e40abb11 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -308,6 +308,7 @@ test_expect_success 'clone checking out a tag' ' setup_ssh_wrapper () { test_expect_success 'setup ssh wrapper' ' + rm -f "$TRASH_DIRECTORY/ssh-wrapper$X" && cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ "$TRASH_DIRECTORY/ssh-wrapper$X" && GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper$X" && @@ -318,6 +319,7 @@ setup_ssh_wrapper () { } copy_ssh_wrapper_as () { + rm -f "${1%$X}$X" && cp "$TRASH_DIRECTORY/ssh-wrapper$X" "${1%$X}$X" && GIT_SSH="${1%$X}$X" && export GIT_SSH diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index f5929c46f3..6e5031f56f 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -452,7 +452,7 @@ test_expect_success 'checking out a commit before submodule moved needs manual u git mv sub sub2 && git commit -m "moved sub to sub2" && git checkout -q HEAD^ 2>actual && - test_i18ngrep "^warning: unable to rmdir sub2:" actual && + test_i18ngrep "^warning: unable to rmdir '\''sub2'\'':" actual && git status -s sub2 >actual && echo "?? sub2/" >expected && test_cmp expected actual && diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index f0f1abd1c2..865168ec6a 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -570,4 +570,18 @@ test_expect_success 'command with underscores does not complain' ' test_cmp expect actual ' +test_expect_success TTY 'git tag with auto-columns ' ' + test_commit one && + test_commit two && + test_commit three && + test_commit four && + test_commit five && + cat >expect <<-\EOF && + initial one two three four five + EOF + test_terminal env PAGER="cat >actual" COLUMNS=80 \ + git -c column.ui=auto tag --sort=authordate && + test_cmp expect actual +' + test_done diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index fc6013ba3c..0c394cf995 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -272,4 +272,15 @@ test_expect_success 'status ignored tracked directory with uncommitted file in t test_cmp expected actual ' +cat >expected <<\EOF +!! tracked/submodule/ +EOF + +test_expect_success 'status ignores submodule in excluded directory' ' + git init tracked/submodule && + test_commit -C tracked/submodule initial && + git status --porcelain --ignored -u tracked/submodule >actual && + test_cmp expected actual +' + test_done diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index a3d388228a..50bca62def 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -27,9 +27,7 @@ cat << EOF # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, -# MA 02111-1307 USA +# along with this program; if not, see <http://www.gnu.org/licenses/>. # EOF } diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 2cb999ecfa..fc614dcbfa 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1245,6 +1245,10 @@ test_expect_success 'double dash "git checkout"' ' --conflict= --orphan Z --patch Z + --detach Z + --ignore-skip-worktree-bits Z + --recurse-submodules Z + --no-recurse-submodules Z EOF ' diff --git a/t/test-lib.sh b/t/test-lib.sh index 9b61f16f7a..116bd6a70c 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -175,9 +175,10 @@ esac # Convenience # -# A regexp to match 5 and 40 hexdigits +# A regexp to match 5, 35 and 40 hexdigits _x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05" +_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05" +_x40="$_x35$_x05" # Zero SHA-1 _z40=0000000000000000000000000000000000000000 @@ -193,7 +194,7 @@ LF=' # when case-folding filenames u200c=$(printf '\342\200\214') -export _x05 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB +export _x05 _x35 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB # Each test should start with something like this, after copyright notices: # @@ -18,8 +18,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "cache.h" diff --git a/worktree.c b/worktree.c index 70015629dc..f8c40f2f5f 100644 --- a/worktree.c +++ b/worktree.c @@ -327,7 +327,8 @@ const struct worktree *find_shared_symref(const char *symref, refs = get_worktree_ref_store(wt); symref_target = refs_resolve_ref_unsafe(refs, symref, 0, NULL, &flags); - if ((flags & REF_ISSYMREF) && !strcmp(symref_target, target)) { + if ((flags & REF_ISSYMREF) && + symref_target && !strcmp(symref_target, target)) { existing = wt; break; } @@ -569,7 +569,7 @@ static int warn_if_unremovable(const char *op, const char *file, int rc) if (!rc || errno == ENOENT) return 0; err = errno; - warning_errno("unable to %s %s", op, file); + warning_errno("unable to %s '%s'", op, file); errno = err; return rc; } @@ -583,7 +583,7 @@ int unlink_or_msg(const char *file, struct strbuf *err) if (!rc || errno == ENOENT) return 0; - strbuf_addf(err, "unable to unlink %s: %s", + strbuf_addf(err, "unable to unlink '%s': %s", file, strerror(errno)); return -1; } @@ -653,9 +653,9 @@ void write_file_buf(const char *path, const char *buf, size_t len) { int fd = xopen(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (write_in_full(fd, buf, len) < 0) - die_errno(_("could not write to %s"), path); + die_errno(_("could not write to '%s'"), path); if (close(fd)) - die_errno(_("could not close %s"), path); + die_errno(_("could not close '%s'"), path); } void write_file(const char *path, const char *fmt, ...) diff --git a/wt-status.c b/wt-status.c index 29bc64cc02..94e5ebaf8b 100644 --- a/wt-status.c +++ b/wt-status.c @@ -2262,8 +2262,10 @@ int has_unstaged_changes(int ignore_submodules) int result; init_revisions(&rev_info, NULL); - if (ignore_submodules) + if (ignore_submodules) { DIFF_OPT_SET(&rev_info.diffopt, IGNORE_SUBMODULES); + DIFF_OPT_SET(&rev_info.diffopt, OVERRIDE_SUBMODULE_CONFIG); + } DIFF_OPT_SET(&rev_info.diffopt, QUICK); diff_setup_done(&rev_info.diffopt); result = run_diff_files(&rev_info, 0); diff --git a/xdiff-interface.c b/xdiff-interface.c index 018e033089..770e1f7f81 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -5,6 +5,7 @@ #include "xdiff/xdiffi.h" #include "xdiff/xemit.h" #include "xdiff/xmacros.h" +#include "xdiff/xutils.h" struct xdiff_emit_state { xdiff_emit_consume_fn consume; @@ -296,6 +297,17 @@ void xdiff_clear_find_func(xdemitconf_t *xecfg) } } +unsigned long xdiff_hash_string(const char *s, size_t len, long flags) +{ + return xdl_hash_record(&s, s + len, flags); +} + +int xdiff_compare_lines(const char *l1, long s1, + const char *l2, long s2, long flags) +{ + return xdl_recmatch(l1, s1, l2, s2, flags); +} + int git_xmerge_style = -1; int git_xmerge_config(const char *var, const char *value, void *cb) diff --git a/xdiff-interface.h b/xdiff-interface.h index 6f6ba9095d..135fc05d72 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -29,4 +29,20 @@ extern void xdiff_clear_find_func(xdemitconf_t *xecfg); extern int git_xmerge_config(const char *var, const char *value, void *cb); extern int git_xmerge_style; +/* + * Compare the strings l1 with l2 which are of size s1 and s2 respectively. + * Returns 1 if the strings are deemed equal, 0 otherwise. + * The `flags` given as XDF_WHITESPACE_FLAGS determine how white spaces + * are treated for the comparision. + */ +extern int xdiff_compare_lines(const char *l1, long s1, + const char *l2, long s2, long flags); + +/* + * Returns a hash of the string s of length len. + * The `flags` given as XDF_WHITESPACE_FLAGS determine how white spaces + * are treated for the hash. + */ +extern unsigned long xdiff_hash_string(const char *s, size_t len, long flags); + #endif diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index b090ad8eac..785ecb0899 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 93a65680a1..0de1ef463b 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xdiffi.h b/xdiff/xdiffi.h index 8b81206c9a..8f1c7c8b04 100644 --- a/xdiff/xdiffi.h +++ b/xdiff/xdiffi.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xemit.c b/xdiff/xemit.c index 8c88dbde38..6881445e4a 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xemit.h b/xdiff/xemit.h index d29710770c..1b9887e670 100644 --- a/xdiff/xemit.h +++ b/xdiff/xemit.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xinclude.h b/xdiff/xinclude.h index 526ccb344d..f35c4485df 100644 --- a/xdiff/xinclude.h +++ b/xdiff/xinclude.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h index 165a895a93..2809a28ca9 100644 --- a/xdiff/xmacros.h +++ b/xdiff/xmacros.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c index f338ad6c75..1659edb453 100644 --- a/xdiff/xmerge.c +++ b/xdiff/xmerge.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c index 9f91702de7..a44e776328 100644 --- a/xdiff/xpatience.c +++ b/xdiff/xpatience.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index 13b55aba74..abeb8fb84e 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xprepare.h b/xdiff/xprepare.h index 8fb06a5374..947d9fc1bb 100644 --- a/xdiff/xprepare.h +++ b/xdiff/xprepare.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xtypes.h b/xdiff/xtypes.h index 2511aef8d8..8442bd436e 100644 --- a/xdiff/xtypes.h +++ b/xdiff/xtypes.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 04d7b32e4e..088001db4f 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 4646ce5752..fba7bae03c 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -13,8 +13,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see + * <http://www.gnu.org/licenses/>. * * Davide Libenzi <davidel@xmailserver.org> * |