resolve_ref() may return a pointer to a shared buffer and can be
overwritten by the next resolve_ref() calls. Callers need to
pay attention, not to keep the pointer when the next call happens.
Rename with "_unsafe" suffix to warn developers (or reviewers) before
introducing new call sites.
This patch is generated using the following command
git grep -l 'resolve_ref(' -- '*.[ch]'|xargs sed -i 's/resolve_ref(/resolve_ref_unsafe(/g'
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is the follow up of c689332 (Convert many resolve_ref() calls to
read_ref*() and ref_exists() - 2011-11-13). See the said commit for
rationale.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
resolve_ref() may return a pointer to a static buffer. Callers that
use this value longer than a couple of statements should copy the
value to avoid some hidden resolve_ref() call that may change the
static buffer's value.
The bug found by Tony Wang <wwwjfy@gmail.com> in builtin/merge.c
demonstrates this. The first call is in cmd_merge()
branch = resolve_ref("HEAD", head_sha1, 0, &flag);
Then deep in lookup_commit_or_die() a few lines after, resolve_ref()
may be called again and destroy "branch".
lookup_commit_or_die
lookup_commit_reference
lookup_commit_reference_gently
parse_object
lookup_replace_object
do_lookup_replace_object
prepare_replace_object
for_each_replace_ref
do_for_each_ref
get_loose_refs
get_ref_dir
get_ref_dir
resolve_ref
All call sites are checked and made sure that xstrdup() is called if
the value should be saved.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The comment on top of stripspace() claims that the buffer
will no longer be NUL-terminated. However, this has not been
the case at least since the move to using strbuf in 2007.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Back in 1127148 (Loosen "working file will be lost" check in
Porcelain-ish - 2006-12-04), git-checkout.sh learned to quietly
overwrite ignored files. Howver the code only took .gitignore files
into account.
Standard ignored files include all specified in .gitignore files in
working directory _and_ $GIT_DIR/info/exclude. This patch makes sure
ignored files in info/exclude can also be overwritten automatically in
the spirit of the original patch.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The option --force should not put us in 'create branch' mode. The
fact that this option is only valid in 'create branch' mode is
already caught by the the next 'if' in which we assure that we
are in the correct mode.
Without this patch, "git branch -f" without any other argument ends
up calling create_branch without any branch name.
Signed-off-by: Vincent van Ravesteijn <vfr@lyx.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The "git cherry-pick --abort" command currently renames the
.git/sequencer directory to .git/sequencer-old instead of removing it
on success due to an accident. cherry-pick --abort is designed to
work in three steps:
1) find which commit to roll back to
2) call "git reset --merge <commit>" to move to that commit
3) remove the .git/sequencer directory
But the careless author forgot step 3 entirely. The only reason the
command worked anyway is that "git reset --merge <commit>" renames the
.git/sequencer directory as a secondary effect --- after moving to
<commit>, or so the logic goes, it is unlikely but possible that the
caller of git reset wants to continue the series of cherry-picks that
was in progress, so git renames the sequencer state to
.git/sequencer-old to be helpful while allowing the cherry-pick to be
resumed if the caller did not want to end the sequence after all.
By running "git cherry-pick --abort", the operator has clearly
indicated that she is not planning to continue cherry-picking. Remove
the (renamed) .git/sequencer directory as intended all along.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
On Windows, it is not possible to rename or remove a directory that has
open files. 'revert --abort' renamed .git/sequencer when it still had
.git/sequencer/head open. Close the file as early as possible to allow
the rename operation on Windows.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Acked-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This fixes the following warning.
CC builtin/revert.o
builtin/revert.c: In function ‘write_cherry_pick_head’:
builtin/revert.c:311: warning: format not a string literal and no format arguments
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Remove the "git cherry-pick --reset" option, which has a different
preferred spelling nowadays ("--quit"). Luckily the old --reset name
was not around long enough for anyone to get used to it.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
After running some ill-advised command like "git cherry-pick
HEAD..linux-next", the bewildered novice may want to return to more
familiar territory. Introduce a "git cherry-pick --abort" command
that rolls back the entire cherry-pick sequence and places the
repository back on solid ground.
Just like "git merge --abort", this internally uses "git reset
--merge", so local changes not involved in the conflict resolution are
preserved.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When conflicts are encountered while reverting a commit, it can be
handy to have the name of that commit easily available. For example,
to produce a copy of the patch to refer to while resolving conflicts:
$ git revert 2eceb2a8
error: could not revert 2eceb2a8... awesome, buggy feature
$ git show -R REVERT_HEAD >the-patch
$ edit $(git diff --name-only)
Set a REVERT_HEAD pseudoref when "git revert" does not make a commit,
for cases like this. This also makes it possible for scripts to
distinguish between a revert that encountered conflicts and other
sources of an unmerged index.
After successfully committing, resetting with "git reset", or moving
to another commit with "git checkout" or "git reset", the pseudoref is
no longer useful, so remove it.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
In the spirit of v1.6.3.3~3^2 (refuse to merge during a merge,
2009-07-01), "git cherry-pick" refuses to start a new cherry-pick when
in the middle of an existing conflicted cherry-pick in the following
sequence:
1. git cherry-pick HEAD..origin
2. resolve conflicts
3. git cherry-pick HEAD..origin (instead of "git cherry-pick
--continue", by mistake)
Good. However, the error message on attempting step 3 is more
convoluted than necessary:
$ git cherry-pick HEAD..origin
error: .git/sequencer already exists.
error: A cherry-pick or revert is in progress.
hint: Use --continue to continue the operation
hint: or --quit to forget about it
fatal: cherry-pick failed
Clarify by removing the redundant first "error:" message, simplifying
the advice, and using lower-case and no full stops to be consistent
with other commands that prefix their messages with "error:", so it
becomes
error: a cherry-pick or revert is already in progress
hint: try "git cherry-pick (--continue | --quit)"
fatal: cherry-pick failed
The "fatal: cherry-pick failed" line seems unnecessary, too, but
that can be fixed some other day.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Deal completely with "cherry-pick --quit" and --continue at the
beginning of pick_revisions(), leaving the rest of the function for
the more interesting "git cherry-pick <commits>" case.
No functional change intended. The impact is just to unindent the
code a little.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The option to "git cherry-pick" and "git revert" to discard the
sequencer state introduced by v1.7.8-rc0~141^2~6 (revert: Introduce
--reset to remove sequencer state, 2011-08-04) has a confusing name.
Change it now, while we still have the time.
The new name for "cherry-pick, please get out of my way, since I've
long forgotten about the sequence of commits I was cherry-picking when
you wrote that old .git/sequencer directory" is --quit. Mnemonic:
this is analagous to quiting a program the user is no longer using ---
we just want to get out of the multiple-command cherry-pick procedure
and not to reset HEAD or rewind any other old state.
The "--reset" option is kept as a synonym to minimize the impact. We
might consider dropping it for simplicity in a separate patch, though.
Adjust documentation and tests to use the newly preferred name (--quit)
instead of --reset. While at it, let's clarify the short descriptions
of these operations in "-h" output.
Before:
--reset forget the current operation
--continue continue the current operation
After:
--quit end revert or cherry-pick sequence
--continue resume revert or cherry-pick sequence
Noticed-by: Phil Hord <phil.hord@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
'git merge' can be called without any arguments if merge.defaultToUpstream
is set. However, when merge.defaultToUpstream is not set, the user will be
presented the usage information as if he entered a command with a wrong
syntaxis. Ironically, the usage information confirms that no arguments are
mandatory.
This adds a proper error message telling the user why the command failed. As
a side-effect this can help the user in discovering the possibility to merge
with the upstream branch by setting merge.defaultToUpstream.
Signed-off-by: Vincent van Ravesteijn <vfr@lyx.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Because git_path() calls vsnprintf(), code like
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
die_errno(_("Could not write to '%s'"), git_path("SQUASH_MSG"));
can end up printing an error indicator from vsnprintf() instead of
open() by mistake. Store the path we are trying to write to in a
temporary variable and pass _that_ to die_errno(), so the messages
written by git cherry-pick/revert and git merge can avoid this source
of confusion.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When --reuse-delta is in effect (which is the default), and an existing
pack in the repository has the same object registered twice (e.g. one copy
in a non-delta format and the other copy in a delta against some other
object), an attempt to repack the repository can result in a cyclic delta
dependency, causing write_one() function to infinitely recurse into
itself.
Detect such a case and break the loopy dependency by writing out an object
that is involved in such a loop in the non-delta format.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When receive-pack & fetch-pack are run and store the pack obtained over
the wire to a local repository, they internally run the index-pack command
with the --strict option. Make sure that we reject incoming packfile that
records objects twice to avoid spreading such a damage.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Some of the fatal messages printed by revert and cherry-pick look ugly
like the following:
fatal: Could not open .git/sequencer/todo.: No such file or directory
The culprit here is that these callers of the die_errno() function did not
take it into account that the message string they give to it is followed
by ": <strerror>", hence the message typically should not end with the
full-stop.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
resolve_ref() may return a pointer to a static buffer, which is not
safe for long-term use because if another resolve_ref() call happens,
the buffer may be changed. Many call sites though do not care about
this buffer. They simply check if the return value is NULL or not.
Convert all these call sites to new wrappers to reduce resolve_ref()
calls from 57 to 34. If we change resolve_ref() prototype later on
to avoid passing static buffer out, this helps reduce changes.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We have kept the original "git commit-tree <tree> -p <parent> ..." syntax
forever, but "git commit-tree -p <parent> -p <parent> ... <tree>" would be
more intuitive way to spell it. Dashed flags along with their arguments
come first and then the "thing" argument after the flags.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
After running "git pull $there for-linus" to merge a signed tag, the
integrator may need to amend the resulting merge commit to fix typoes
in it. Teach --amend option to read the existing extra headers, and
carry them forward.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Now that we allow pulling a tag from the remote site to validate the
authenticity, we should give the user the final chance to verify and edit
the merge message. The integrator is expected to leave a meaningful merge
commit log in the history. Disallow fast-forwarding in such a case to
ensure that a merge commit is always recorded.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Now MERGE_HEAD records the tag objects without peeling, we could record
the result of manual conflict resolution via "git commit" without losing
the tag information. Introduce a new "mergetag" multi-line header field to
the commit object, and use it to store the entire contents of each signed
tag merged.
A commit header that has a multi-line payload begins with the header tag
(e.g. "mergetag" in this case), SP, the first line of payload, LF, and all
the remaining lines have a SP inserted at the beginning.
In hindsight, it would have been better to make "merge --continue" as the
way to continue from such an interrupted merge, not "commit", but this is
a backward compatibility baggage we would need to carry around for now.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Otherwise, "git commit" wouldn't have a way to tell that we were in the
middle of merging an annotated or signed tag, not a plain commit, after
"git merge" stops to ask the user to resolve conflicts.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The merge-recursive code uses the commit->util field directly to annotate
the commit objects given from the command line, i.e. the remote heads to
be merged, with a single string to be used to describe it in its trace
messages and conflict markers.
Correct this short-signtedness by redefining the field to be a pointer to
a structure "struct merge_remote_desc" that later enhancements can add
more information. Store the original objects we were told to merge in a
field "obj" in this struct, so that we can recover the tag we were told to
merge.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When a contributor asks the integrator to merge her history, a signed tag
can be a good vehicle to communicate the authenticity of the request while
conveying other information such as the purpose of the topic.
E.g. a signed tag "for-linus" can be created, and the integrator can run:
$ git pull git://example.com/work.git/ for-linus
This would allow the integrator to run "git verify-tag FETCH_HEAD" to
validate the signed tag.
Update fmt-merge-msg so that it pre-fills the merge message template with
the body (but not signature) of the tag object to help the integrator write
a better merge message, in the same spirit as the existing merge.log summary
lines.
The message that comes from GPG signature validation is also included in
the merge message template to help the integrator verify it, but they are
prefixed with "#" to make them comments.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
prune already shows progress meter while pruning. The marking part may
take a few seconds or more, depending on repository size. Show
progress meter during this time too.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2564aa4 started to initialize buf.alloc, but that should actually be one
more byte than the string length due to the trailing \0. Also, do not
modify buf.alloc out of the strbuf code. Use the existing strbuf_attach
instead.
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
In various places in the codepath, the program tries to return early
assuming there is no more work needed. That is generally untrue when
over time new features are added.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This also updates the autogenerated merge title message from "merge commit X"
to "merge tag X", and its effect can be seen in the changes to the test suite.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Bad copy-paste.
Otherwise "git remote set-branches" without necessary argument
will result in an error message and help for set-url subcommand.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fsck is usually a long process and it would be nice if it prints
progress from time to time.
Progress meter is not printed when --verbose is given because
--verbose prints a lot, there's no need for "alive" indicator.
Progress meter may provide "% complete" information but it would
be lost anyway in the flood of text.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
During verify_pack() all objects are read for SHA-1 check. Then
fsck_sha1() is called on every object, which read the object again
(fsck_sha1 -> parse_object -> read_sha1_file).
Avoid reading an object twice, do fsck_sha1 while we have an object
uncompressed data in verify_pack.
On git.git, with this patch I got:
$ /usr/bin/time ./git fsck >/dev/null
98.97user 0.90system 1:40.01elapsed 99%CPU (0avgtext+0avgdata 616624maxresident)k
0inputs+0outputs (0major+194186minor)pagefaults 0swaps
Without it:
$ /usr/bin/time ./git fsck >/dev/null
231.23user 2.35system 3:53.82elapsed 99%CPU (0avgtext+0avgdata 636688maxresident)k
0inputs+0outputs (0major+461629minor)pagefaults 0swaps
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Both of these free() calls are freeing a "const unsigned char (*)[20]"
type while free() expects a "void *". This results in the following
warning under clang 2.9:
builtin/diff.c:185:7: warning: passing 'const unsigned char (*)[20]' to parameter of type 'void *' discards qualifiers
free(parent);
^~~~~~
submodule.c:394:7: warning: passing 'const unsigned char (*)[20]' to parameter of type 'void *' discards qualifiers
free(parents);
^~~~~~~
This free()-ing without a cast was added by Jim Meyering to
builtin/diff.c in v1.7.6-rc3~4 and later by Fredrik Gustafsson in
submodule.c in v1.7.7-rc1~25^2.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
According to the C standard size_t is always unsigned, therefore the
comparison "n1 < 0 || n2 < 0" when n1 and n2 are size_t will always be
false.
This was raised by clang 2.9 which throws this warning when compiling
apply.c:
builtin/apply.c:253:9: warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
if (n1 < 0 || n2 < 0)
~~ ^ ~
builtin/apply.c:253:19: warning: comparison of unsigned expression < 0 is always false [-Wtautological-compare]
if (n1 < 0 || n2 < 0)
~~ ^ ~
This check was originally added in v1.6.5-rc0~53^2 by Giuseppe Bilotta
while adding an option to git-apply to ignore whitespace differences.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We do not want to record tags as parents of a merge when the user does
"git pull $there tag v1.0" to merge tagged commit, but that is not a good
enough excuse to peel the tag down to commit when storing in FETCH_HEAD.
The caller of underlying "git fetch $there tag v1.0" may have other uses
of information contained in v1.0 tag in mind.
[jc: the test adjustment is to update for the new expectation]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This mostly moves existing code from builtin/tag.c (for signing)
and builtin/verify-tag.c (for verifying) to a new gpg-interface.c
file to provide a more generic library interface.
- sign_buffer() takes a payload strbuf, a signature strbuf, and a signing
key, runs "gpg" to produce a detached signature for the payload, and
appends it to the signature strbuf. The contents of a signed tag that
concatenates the payload and the detached signature can be produced by
giving the same strbuf as payload and signature strbuf.
- verify_signed_buffer() takes a payload and a detached signature as
<ptr, len> pairs, and runs "gpg --verify" to see if the payload matches
the signature. It can optionally capture the output from GPG to allow
the callers to pretty-print it in a way more suitable for their
contexts.
"verify-tag" (aka "tag -v") used to save the whole tag contents as if it
is a detached signature, and fed gpg the payload part of the tag. It
relied on gpg to fail when the given tag is not signed but just is
annotated. The updated run_gpg_verify() function detects the lack of
detached signature in the input, and errors out without bothering "gpg".
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When pushing to delete a ref, it uses 0{40} as an object name to signal
that the request is a deletion. We shouldn't trigger "deletion of a
corrupt ref" warning in such a case, which was designed to notice that a
ref points at an object that is truly missing from the repository.
Reported-by: Stefan Näwe
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Modify the option parsing heuristic to handle all -m (rename) cases,
including the no-arg case.
Previously, this "fell through" to the (argc <= 2) case and caused
segfault.
Reported-by: Stefan Näwe <stefan.naewe@atlas-elektronik.com>
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The POSIX-function fork is not supported on Windows. Use our
start_command API instead.
As this is the last call-site that depends on the fork-stub in
compat/mingw.h, remove that as well.
Add an undocumented flag to git-archive that tells it that the
action originated from a remote, so features can be disabled.
Thanks to Jeff King for work on this part.
Remove the NOT_MINGW-prereq for t5000, as git-archive --remote
now works.
Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
For a plain string where only the length is known, strbuf.alloc needs to
be initialized to the length. Otherwise strbuf.alloc is 0 and a later
call to strbuf_setlen() will fail.
This bug surfaced when calling git blame under Windows on a *.doc file.
The *.doc file is converted to plain text by antiword via the textconv
mechanism. However, the plain text returned by antiword contains DOS line
endings instead of Unix line endings which triggered the strbuf_setlen()
which previous to this patch failed.
Signed-off-by: Sebastian Schuberth <sschuberth@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Without this patch,
$ git clone foo .
results in this:
Cloning into ....
done.
With it:
Cloning into '.'...
done.
Signed-off-by: Richard Hartmann <richih.mailinglist@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>