summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
2018-11-21Merge branch 'jt/lazy-object-fetch-fix' into maintLibravatar Junio C Hamano5-19/+22
The code to backfill objects in lazily cloned repository did not work correctly, which has been corrected. * jt/lazy-object-fetch-fix: fetch-object: set exact_oid when fetching fetch-object: unify fetch_object[s] functions
2018-11-21Merge branch 'en/sequencer-empty-edit-result-aborts' into maintLibravatar Junio C Hamano4-17/+14
"git rebase" etc. in Git 2.19 fails to abort when given an empty commit log message as result of editing, which has been corrected. * en/sequencer-empty-edit-result-aborts: sequencer: fix --allow-empty-message behavior, make it smarter
2018-11-21Merge branch 'nd/attr-pathspec-fix' into maintLibravatar Junio C Hamano2-2/+2
"git add ':(attr:foo)'" is not supported and is supposed to be rejected while the command line arguments are parsed, but we fail to reject such a command line upfront. * nd/attr-pathspec-fix: add: do not accept pathspec magic 'attr'
2018-11-21Merge branch 'en/rerere-multi-stage-1-fix' into maintLibravatar Junio C Hamano2-1/+30
A corner case bugfix in "git rerere" code. * en/rerere-multi-stage-1-fix: rerere: avoid buffer overrun t4200: demonstrate rerere segfault on specially crafted merge
2018-11-21Merge branch 'js/mingw-o-append' into maintLibravatar Junio C Hamano6-3/+129
Further fix for O_APPEND emulation on Windows * js/mingw-o-append: mingw: fix mingw_open_append to work with named pipes t0051: test GIT_TRACE to a windows named pipe
2018-11-21Merge branch 'jk/reopen-tempfile-truncate' into maintLibravatar Junio C Hamano4-5/+23
Fix for a long-standing bug that leaves the index file corrupt when it shrinks during a partial commit. * jk/reopen-tempfile-truncate: reopen_tempfile(): truncate opened file
2018-11-21Merge branch 'bp/mv-submodules-with-fsmonitor' into maintLibravatar Junio C Hamano1-2/+1
When fsmonitor is in use, after operation on submodules updates .gitmodules, we lost track of the fact that we did so and relied on stale fsmonitor data. * bp/mv-submodules-with-fsmonitor: git-mv: allow submodules and fsmonitor to work together
2018-11-21Merge branch 'js/rebase-i-autosquash-fix' into maintLibravatar Junio C Hamano2-3/+33
"git rebase -i" did not clear the state files correctly when a run of "squash/fixup" is aborted and then the user manually amended the commit instead, which has been corrected. * js/rebase-i-autosquash-fix: rebase -i: be careful to wrap up fixup/squash chains rebase -i --autosquash: demonstrate a problem skipping the last squash
2018-11-21Merge branch 'jk/trailer-fixes' into maintLibravatar Junio C Hamano14-39/+175
"git interpret-trailers" and its underlying machinery had a buggy code that attempted to ignore patch text after commit log message, which triggered in various codepaths that will always get the log message alone and never get such an input. * jk/trailer-fixes: append_signoff: use size_t for string offsets sequencer: ignore "---" divider when parsing trailers pretty, ref-filter: format %(trailers) with no_divider option interpret-trailers: allow suppressing "---" divider interpret-trailers: tighten check for "---" patch boundary trailer: pass process_trailer_opts to trailer_info_get() trailer: use size_t for iterating trailer list trailer: use size_t for string offsets
2018-09-27Git 2.19.1Libravatar Junio C Hamano3-2/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27Sync with 2.18.1Libravatar Junio C Hamano10-0/+148
* maint-2.18: Git 2.18.1 Git 2.17.2 fsck: detect submodule paths starting with dash fsck: detect submodule urls starting with dash Git 2.16.5 Git 2.15.3 Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options
2018-09-27Git 2.18.1Libravatar Junio C Hamano3-2/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27Sync with 2.17.2Libravatar Junio C Hamano9-0/+142
* maint-2.17: Git 2.17.2 fsck: detect submodule paths starting with dash fsck: detect submodule urls starting with dash Git 2.16.5 Git 2.15.3 Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options
2018-09-27Git 2.17.2Libravatar Junio C Hamano3-2/+14
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27fsck: detect submodule paths starting with dashLibravatar Jeff King2-0/+15
As with urls, submodule paths with dashes are ignored by git, but may end up confusing older versions. Detecting them via fsck lets us prevent modern versions of git from being a vector to spread broken .gitmodules to older versions. Compared to blocking leading-dash urls, though, this detection may be less of a good idea: 1. While such paths provide confusing and broken results, they don't seem to actually work as option injections against anything except "cd". In particular, the submodule code seems to canonicalize to an absolute path before running "git clone" (so it passes /your/clone/-sub). 2. It's more likely that we may one day make such names actually work correctly. Even after we revert this fsck check, it will continue to be a hassle until hosting servers are all updated. On the other hand, it's not entirely clear that the behavior in older versions is safe. And if we do want to eventually allow this, we may end up doing so with a special syntax anyway (e.g., writing "./-sub" in the .gitmodules file, and teaching the submodule code to canonicalize it when comparing). So on balance, this is probably a good protection. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27fsck: detect submodule urls starting with dashLibravatar Jeff King2-0/+22
Urls with leading dashes can cause mischief on older versions of Git. We should detect them so that they can be rejected by receive.fsckObjects, preventing modern versions of git from being a vector by which attacks can spread. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27Sync with 2.16.5Libravatar Junio C Hamano7-0/+93
* maint-2.16: Git 2.16.5 Git 2.15.3 Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options
2018-09-27Git 2.16.5Libravatar Junio C Hamano3-2/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27Sync with 2.15.3Libravatar Junio C Hamano6-0/+87
* maint-2.15: Git 2.15.3 Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options
2018-09-27Git 2.15.3Libravatar Junio C Hamano3-2/+8
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27Sync with Git 2.14.4Libravatar Junio C Hamano5-0/+81
* maint-2.14: Git 2.14.5 submodule-config: ban submodule paths that start with a dash submodule-config: ban submodule urls that start with dash submodule--helper: use "--" to signal end of clone options
2018-09-27Git 2.14.5Libravatar Junio C Hamano3-2/+18
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27submodule-config: ban submodule paths that start with a dashLibravatar Jeff King2-0/+22
We recently banned submodule urls that look like command-line options. This is the matching change to ban leading-dash paths. As with the urls, this should not break any use cases that currently work. Even with our "--" separator passed to git-clone, git-submodule.sh gets confused. Without the code portion of this patch, the clone of "-sub" added in t7417 would yield results like: /path/to/git-submodule: 410: cd: Illegal option -s /path/to/git-submodule: 417: cd: Illegal option -s /path/to/git-submodule: 410: cd: Illegal option -s /path/to/git-submodule: 417: cd: Illegal option -s Fetched in submodule path '-sub', but it did not contain b56243f8f4eb91b2f1f8109452e659f14dd3fbe4. Direct fetching of that commit failed. Moreover, naively adding such a submodule doesn't work: $ git submodule add $url -sub The following path is ignored by one of your .gitignore files: -sub even though there is no such ignore pattern (the test script hacks around this with a well-placed "git mv"). Unlike leading-dash urls, though, it's possible that such a path _could_ be useful if we eventually made it work. So this commit should be seen not as recommending a particular policy, but rather temporarily closing off a broken and possibly dangerous code-path. We may revisit this decision later. There are two minor differences to the tests in t7416 (that covered urls): 1. We don't have a "./-sub" escape hatch to make this work, since the submodule code expects to be able to match canonical index names to the path field (so you are free to add submodule config with that path, but we would never actually use it, since an index entry would never start with "./"). 2. After this patch, cloning actually succeeds. Since we ignore the submodule.*.path value, we fail to find a config stanza for our submodule at all, and simply treat it as inactive. We still check for the "ignoring" message. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27submodule-config: ban submodule urls that start with dashLibravatar Jeff King2-0/+42
The previous commit taught the submodule code to invoke our "git clone $url $path" with a "--" separator so that we aren't confused by urls or paths that start with dashes. However, that's just one code path. It's not clear if there are others, and it would be an easy mistake to add one in the future. Moreover, even with the fix in the previous commit, it's quite hard to actually do anything useful with such an entry. Any url starting with a dash must fall into one of three categories: - it's meant as a file url, like "-path". But then any clone is not going to have the matching path, since it's by definition relative inside the newly created clone. If you spell it as "./-path", the submodule code sees the "/" and translates this to an absolute path, so it at least works (assuming the receiver has the same filesystem layout as you). But that trick does not apply for a bare "-path". - it's meant as an ssh url, like "-host:path". But this already doesn't work, as we explicitly disallow ssh hostnames that begin with a dash (to avoid option injection against ssh). - it's a remote-helper scheme, like "-scheme::data". This _could_ work if the receiver bends over backwards and creates a funny-named helper like "git-remote--scheme". But normally there would not be any helper that matches. Since such a url does not work today and is not likely to do anything useful in the future, let's simply disallow them entirely. That protects the existing "git clone" path (in a belt-and-suspenders way), along with any others that might exist. Our tests cover two cases: 1. A file url with "./" continues to work, showing that there's an escape hatch for people with truly silly repo names. 2. A url starting with "-" is rejected. Note that we expect case (2) to fail, but it would have done so even without this commit, for the reasons given above. So instead of just expecting failure, let's also check for the magic word "ignoring" on stderr. That lets us know that we failed for the right reason. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-27submodule--helper: use "--" to signal end of clone optionsLibravatar Jeff King1-0/+1
When we clone a submodule, we call "git clone $url $path". But there's nothing to say that those components can't begin with a dash themselves, confusing git-clone into thinking they're options. Let's pass "--" to make it clear what we expect. There's no test here, because it's actually quite hard to make these names work, even with "git clone" parsing them correctly. And we're going to restrict these cases even further in future commits. So we'll leave off testing until then; this is just the minimal fix to prevent us from doing something stupid with a badly formed entry. Reported-by: joernchen <joernchen@phenoelit.de> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-21add: do not accept pathspec magic 'attr'Libravatar Nguyễn Thái Ngọc Duy2-2/+2
Commit b0db704652 (pathspec: allow querying for attributes - 2017-03-13) adds new pathspec magic 'attr' but only with match_pathspec(). "git add" has some pathspec related code that still does not know about 'attr' and will bail out: $ git add ':(attr:foo)' fatal: BUG:dir.c:1584: unsupported magic 40 A better solution would be making this code support 'attr'. But I don't know how much work is needed (I'm not familiar with this new magic). For now, let's simply reject this magic with a friendlier message: $ git add ':(attr:foo)' fatal: :(attr:foo): pathspec magic not supported by this command: 'attr' Update t6135 so that the expected error message is from the "graceful" rejection codepath, not "oops, we were supposed to reject the request to trigger this magic" codepath. Reported-by: smaudet@sebastianaudet.com Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-13fetch-object: set exact_oid when fetchingLibravatar Jonathan Tan2-0/+13
fetch_objects() currently does not set exact_oid in struct ref when invoking transport_fetch_refs(). If the server supports ref-in-want, fetch_pack() uses this field to determine whether a wanted ref should be requested as a "want-ref" line or a "want" line; without the setting of exact_oid, the wrong line will be sent. Set exact_oid, so that the correct line is sent. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-13fetch-object: unify fetch_object[s] functionsLibravatar Jonathan Tan4-19/+9
There are fetch_object() and fetch_objects() helpers in fetch-object.h; as the latter takes "struct oid_array", the former cannot be made into a thin wrapper around the latter without an extra allocation and set-up cost. Update fetch_objects() to take an array of "struct object_id" and number of elements in it as separate parameters, remove fetch_object(), and adjust all existing callers of these functions to use the new fetch_objects(). Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-13sequencer: fix --allow-empty-message behavior, make it smarterLibravatar Elijah Newren4-17/+14
In commit b00bf1c9a8dd ("git-rebase: make --allow-empty-message the default", 2018-06-27), several arguments were given for transplanting empty commits without halting and asking the user for confirmation on each commit. These arguments were incomplete because the logic clearly assumed the only cases under consideration were transplanting of commits with empty messages (see the comment about "There are two sources for commits with empty messages). It didn't discuss or even consider rewords, squashes, etc. where the user is explicitly asked for a new commit message and provides an empty one. (My bad, I totally should have thought about that at the time, but just didn't.) Rewords and squashes are significantly different, though, as described by SZEDER: Let's suppose you start an interactive rebase, choose a commit to squash, save the instruction sheet, rebase fires up your editor, and then you notice that you mistakenly chose the wrong commit to squash. What do you do, how do you abort? Before [that commit] you could clear the commit message, exit the editor, and then rebase would say "Aborting commit due to empty commit message.", and you get to run 'git rebase --abort', and start over. But [since that commit, ...] saving the commit message as is would let rebase continue and create a bunch of unnecessary objects, and then you would have to use the reflog to return to the pre-rebase state. Also, he states: The instructions in the commit message template, which is shown for 'reword' and 'squash', too, still say... # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. These are sound arguments that when editing commit messages during a sequencer operation, that if the commit message is empty then the operation should halt and ask the user to correct. The arguments in commit b00bf1c9a8dd (referenced above) still apply when transplanting previously created commits with empty commit messages, so the sequencer should not halt for those. Furthermore, all rationale so far applies equally for cherry-pick as for rebase. Therefore, make the code default to --allow-empty-message when transplanting an existing commit, and to default to halting when the user is asked to edit a commit message and provides an empty one -- for both rebase and cherry-pick. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-12git-mv: allow submodules and fsmonitor to work togetherLibravatar Ben Peart1-2/+1
It was reported that GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh breaks as the fsmonitor data is out of sync with the state of the .gitmodules file. Update is_staging_gitmodules_ok() so that it no longer tells ie_match_stat() to ignore refreshing the fsmonitor data. Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Helped-by: Stefan Beller <sbeller@google.com> Signed-off-by: Ben Peart <benpeart@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-11mingw: fix mingw_open_append to work with named pipesLibravatar Jeff Hostetler2-4/+34
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Acked-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-11t0051: test GIT_TRACE to a windows named pipeLibravatar Jeff Hostetler5-0/+96
Create a test-tool helper to create the server side of a windows named pipe, wait for a client connection, and copy data written to the pipe to stdout. Create t0051 test to route GIT_TRACE output of a command to a named pipe using the above test-tool helper. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-11rerere: avoid buffer overrunLibravatar Elijah Newren2-2/+2
check_one_conflict() compares `i` to `active_nr` in two places to avoid buffer overruns, but left out an important third location. The code did used to have a check here comparing i to active_nr, back before commit fb70a06da2f1 ("rerere: fix an off-by-one non-bug", 2015-06-28), however the code at the time used an 'if' rather than a 'while' meaning back then that this loop could not have read past the end of the array, making the check unnecessary and it was removed. Unfortunately, in commit 5eda906b2873 ("rerere: handle conflicts with multiple stage #1 entries", 2015-07-24), the 'if' was changed to a 'while' and the check comparing i and active_nr was not re-instated, leading to this problem. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-11t4200: demonstrate rerere segfault on specially crafted mergeLibravatar Elijah Newren1-0/+29
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-10Git 2.19Libravatar Junio C Hamano2-9/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-10Merge tag 'l10n-2.19.0-rnd2' of git://github.com/git-l10n/git-poLibravatar Junio C Hamano9-25222/+41448
l10n for Git 2.19.0 round 2 * tag 'l10n-2.19.0-rnd2' of git://github.com/git-l10n/git-po: l10n: zh_CN: for git v2.19.0 l10n round 1 to 2 l10n: bg.po: Updated Bulgarian translation (3958t) l10n: vi.po(3958t): updated Vietnamese translation v2.19.0 round 2 l10n: es.po v2.19.0 round 2 l10n: fr.po v2.19.0 rnd 2 l10n: fr.po v2.19.0 rnd 1 l10n: fr: fix a message seen in git bisect l10n: sv.po: Update Swedish translation (3958t0f0u) l10n: git.pot: v2.19.0 round 2 (3 new, 5 removed) l10n: ru.po: update Russian translation l10n: git.pot: v2.19.0 round 1 (382 new, 30 removed) l10n: de.po: translate 108 new messages l10n: zh_CN: review for git 2.18.0 l10n: sv.po: Update Swedish translation(3608t0f0u)
2018-09-10Merge branch 'jn/submodule-core-worktree-revert'Libravatar Junio C Hamano6-55/+2
* jn/submodule-core-worktree-revert: Revert "Merge branch 'sb/submodule-core-worktree'"
2018-09-10Merge branch 'mk/http-backend-content-length'Libravatar Junio C Hamano2-1/+12
The earlier attempt barfed when given a CONTENT_LENGTH that is set to an empty string. RFC 3875 is fairly clear that in this case we should not read any message body, but we've been reading through to the EOF in previous versions (which did not even pay attention to the environment variable), so keep that behaviour for now in this late update. * mk/http-backend-content-length: http-backend: allow empty CONTENT_LENGTH
2018-09-09l10n: zh_CN: for git v2.19.0 l10n round 1 to 2Libravatar Jiang Xin1-2821/+4584
Translate 382 new messages (3958t0f0u) for git 2.19.0. Signed-off-by: Jiang Xin <worldhello.net@gmail.com>
2018-09-09Merge branch 'master' of git://github.com/alshopov/git-poLibravatar Jiang Xin1-2750/+4607
* 'master' of git://github.com/alshopov/git-po: l10n: bg.po: Updated Bulgarian translation (3958t)
2018-09-09l10n: bg.po: Updated Bulgarian translation (3958t)Libravatar Alexander Shopov1-2750/+4607
Signed-off-by: Alexander Shopov <ash@kambanaria.org>
2018-09-07Revert "Merge branch 'sb/submodule-core-worktree'"Libravatar Jonathan Nieder6-55/+2
This reverts commit 7e25437d35a70791b345872af202eabfb3e1a8bc, reversing changes made to 00624d608cc69bd62801c93e74d1ea7a7ddd6598. v2.19.0-rc0~165^2~1 (submodule: ensure core.worktree is set after update, 2018-06-18) assumes an "absorbed" submodule layout, where the submodule's Git directory is in the superproject's .git/modules/ directory and .git in the submodule worktree is a .git file pointing there. In particular, it uses $GIT_DIR/modules/$name to find the submodule to find out whether it already has core.worktree set, and it uses connect_work_tree_and_git_dir if not, resulting in fatal: could not open sub/.git for writing The context behind that patch: v2.19.0-rc0~165^2~2 (submodule: unset core.worktree if no working tree is present, 2018-06-12) unsets core.worktree when running commands like "git checkout --recurse-submodules" to switch to a branch without the submodule. If a user then uses "git checkout --no-recurse-submodules" to switch back to a branch with the submodule and runs "git submodule update", this patch is needed to ensure that commands using the submodule directly are aware of the path to the worktree. It is late in the release cycle, so revert the whole 3-patch series. We can try again later for 2.20. Reported-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Helped-by: Stefan Beller <sbeller@google.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-07http-backend: allow empty CONTENT_LENGTHLibravatar Max Kirillov2-1/+12
According to RFC3875, empty environment variable is equivalent to unset, and for CONTENT_LENGTH it should mean zero body to read. However, unset CONTENT_LENGTH is also used for chunked encoding to indicate reading until EOF. At least, the test "large fetch-pack requests can be split across POSTs" from t5551 starts faliing, if unset or empty CONTENT_LENGTH is treated as zero length body. So keep the existing behavior as much as possible. Add a test for the case. Reported-By: Jelmer Vernooij <jelmer@jelmer.uk> Signed-off-by: Max Kirillov <max@max630.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-09-07l10n: vi.po(3958t): updated Vietnamese translation v2.19.0 round 2Libravatar Tran Ngoc Quan1-2800/+4576
Signed-off-by: Tran Ngoc Quan <vnwildman@gmail.com>
2018-09-06l10n: es.po v2.19.0 round 2Libravatar Christopher Diaz Riveros1-2753/+4571
Signed-off-by: Christopher Diaz Riveros <chrisadr@gentoo.org>
2018-09-06Merge branch 'fr_2.19.0_rnd1' of git://github.com/jnavila/gitLibravatar Jiang Xin1-2786/+4588
* 'fr_2.19.0_rnd1' of git://github.com/jnavila/git: l10n: fr.po v2.19.0 rnd 2 l10n: fr.po v2.19.0 rnd 1 l10n: fr: fix a message seen in git bisect
2018-09-05l10n: fr.po v2.19.0 rnd 2Libravatar Jean-Noël Avila1-283/+328
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
2018-09-05l10n: fr.po v2.19.0 rnd 1Libravatar Jean-Noël Avila1-2718/+4475
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
2018-09-05l10n: fr: fix a message seen in git bisectLibravatar Raphaël Hertzog1-2/+2
"cette" can be only be used before a word (like in "cette bouteille" for "this bottle"), but here "this" refers to the current step and we have to use "ceci" in French. Signed-off-by: Raphaël Hertzog <hertzog@debian.org>
2018-09-05reopen_tempfile(): truncate opened fileLibravatar Jeff King4-5/+23
We provide a reopen_tempfile() function, which is in turn used by reopen_lockfile(). The idea is that a caller may want to rewrite the tempfile without letting go of the lock. And that's what our one caller does: after running add--interactive, "commit -p" will update the cache-tree extension of the index and write out the result, all while holding the lock. However, because we open the file with only the O_WRONLY flag, the existing index content is left in place, and we overwrite it starting at position 0. If the new index after updating the cache-tree is smaller than the original, those final bytes are not overwritten and remain in the file. This results in a corrupt index, since those cruft bytes are interpreted as part of the trailing hash (or even as an extension, if there are enough bytes). This bug actually pre-dates reopen_tempfile(); the original code from 9c4d6c0297 (cache-tree: Write updated cache-tree after commit, 2014-07-13) has the same bug, and those lines were eventually refactored into the tempfile module. Nobody noticed until now for two reasons: - the bug can only be triggered in interactive mode ("commit -p" or "commit -i") - the size of the index must shrink after updating the cache-tree, which implies a non-trivial deletion. Notice that the included test actually has to create a 2-deep hierarchy. A single level is not enough to actually cause shrinkage. The fix is to truncate the file before writing out the second index. We can do that at the caller by using ftruncate(). But we shouldn't have to do that. There is no other place in Git where we want to open a file and overwrite bytes, making reopen_tempfile() a confusing and error-prone interface. Let's pass O_TRUNC there, which gives callers the same state they had after initially opening the file or lock. It's possible that we could later add a caller that wants something else (e.g., to open with O_APPEND). But this is the only caller we've had in the history of the codebase. Let's punt on doing anything more clever until another one comes along. Reported-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>