The old code used to totally mix up the notion of a ref-name and the path
that that ref was associated with. That was not only horribly ugly (a
number of users got the path, and then wanted to try to turn it back into
a ref-name again), but it fundamnetally doesn't work at all once we do any
setup where a ref doesn't have a 1:1 relationship with a particular
pathname.
This fixes things up so that we use the ref-name throughout, and only
turn it into a pathname once we actually look it up in the filesystem.
That makes a lot of things much clearer and more straightforward.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Like xmalloc and xrealloc xstrdup dies with a useful message if
the native strdup() implementation returns NULL rather than a
valid pointer.
I just tried to use xstrdup in new code and found it to be missing.
However I expected it to be present as xmalloc and xrealloc are
already commonly used throughout the code.
[jc: removed the part that deals with last_XXX, which I am
finding more and more dubious these days.]
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This abstracts away the size of the hash values when copying them
from memory location to memory location, much as the introduction
of hashcmp abstracted away hash value comparsion.
A few call sites were using char* rather than unsigned char* so
I added the cast rather than open hashcpy to be void*. This is a
reasonable tradeoff as most call sites already use unsigned char*
and the existing hashcmp is also declared to be unsigned char*.
[jc: Splitted the patch to "master" part, to be followed by a
patch for merge-recursive.c which is not in "master" yet.
Fixed the cast in the latter hunk to combine-diff.c which was
wrong in the original.
Also converted ones left-over in combine-diff.c, diff-lib.c and
upload-pack.c ]
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Introduces global inline:
hashcmp(const unsigned char *sha1, const unsigned char *sha2)
Uses memcmp for comparison and returns the result based on the length of
the hash name (a future runtime decision).
Acked-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Replace sha1 comparisons to null_sha1 with a global inline (which previously an
unused static inline in builtin-apply.c)
[jc: with a fix from Jonas Fonseca.]
Signed-off-by: David Rientjes <rientjes@google.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This updates the type-enumeration constants introduced to reduce
the memory footprint of "struct object" to match the type bits
already used in the packfile format, by removing the former
(i.e. TYPE_* constant macros) and using the latter (i.e. enum
object_type) throughout the code for consistency.
Eventually we can stop passing around the "type strings"
entirely, and this will help - no confusion about two different
integer enumeration.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This introduces a setup_git() function which is essentialy a (public)
backend for setup_git_env() which lets anyone specify custom sources
for the various paths instead of environment variables. Since the repositories
may get switched on the fly, this also updates code that caches paths to
invalidate them properly; I hope neither of those is a sweet spot.
It is used by Git.xs' xs__call_gate() to set up per-repository data
for libgit's consumption. No code actually takes advantage of it yet
but get_object() will in the next patches.
Signed-off-by: Petr Baudis <pasky@suse.cz>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This cleans up the use of safe_strncpy() even more. Since it has the
same semantics as strlcpy() use this name instead. Also move the
definition from inside path.c to its own file compat/strlcpy.c, and use
it conditionally at compile time, since some platforms already has
strlcpy(). It's included in the same way as compat/setenv.c.
Signed-off-by: Peter Eriksen <s022018@student.dtu.dk>
Signed-off-by: Junio C Hamano <junkio@cox.net>
This shrinks "struct object" by a small amount, by getting rid of the
"struct type *" pointer and replacing it with a 3-bit bitfield instead.
In addition, we merge the bitfields and the "flags" field, which
incidentally should also remove a useless 4-byte padding from the object
when in 64-bit mode.
Now, our "struct object" is still too damn large, but it's now less
obviously bloated, and of the remaining fields, only the "util" (which is
not used by most things) is clearly something that should be eventually
discarded.
This shrinks the "git-rev-list --all" memory use by about 2.5% on the
kernel archive (and, perhaps more importantly, on the larger mozilla
archive). That may not sound like much, but I suspect it's more on a
64-bit platform.
There are other remaining inefficiencies (the parent lists, for example,
probably have horrible malloc overhead), but this was pretty obvious.
Most of the patch is just changing the comparison of the "type" pointer
from one of the constant string pointers to the appropriate new TYPE_xxx
small integer constant.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Its ambiguous to parse "master@2006-05-17 18:30:foo" when foo is
meant as a file name and ":30" is meant as 30 minutes past 6 pm.
Therefore all date specifications in a sha1 expression must now
appear within brackets and the ':' splitter used for the path name
in a sha1 expression ignores ':' appearing within brackets.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
The log parser was only ever matching the last log record due to
calling strtoul on "> 1136091609" rather than " 1136091609". Also
once a match for '@' has been found after the name of the ref there
is no point in looking for another '@' within the remaining text.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Extended sha1 expressions may now include date specifications
which indicate a point in time within the local repository's
history. If the ref indicated to the left of '@' has a log in
$GIT_DIR/logs/<ref> then the value of the ref at the time indicated
by the specification is obtained from the ref's log.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Earlier patch to say <ent>:<path> by Linus was very useful, and
this extends the same idea to the current index. An sha1
expression :<path> extracts the object name for the named path
from the current index.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This is a fairly straightforward patch to allow "get_sha1()" to also have
shorthands for tree and blob objects.
The syntax is very simple and intuitive: you can specify a tree or a blob
by simply specifying <revision>:<path>, and get_sha1() will do the SHA1
lookup from the tree for you.
You can currently do it with "git ls-tree <rev> <path>" and parsing the
output, but that's actually pretty awkward.
With this, you can do something like
git cat-file blob v1.2.4:Makefile
to get the contents of "Makefile" at revision v1.2.4.
Now, this isn't necessarily something you really need all that often, but
the concept itself is actually pretty powerful. We could, for example,
allow things like
git diff v0.99.6:git-commit-script..v1.3.0:git-commit.sh
to see the difference between two arbitrary files in two arbitrary
revisions. To do that, the only thing we'd have to do is to make
git-diff-tree accept two blobs to diff, in addition to the two trees it
now expects.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This makes sure that many commands that take refs on the command
line to honor core.warnambiguousrefs configuration. Earlier,
the commands affected by this patch did not read the
configuration file.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This implements the suggestion by Jeff King to use
refs/remotes/$foo/HEAD to interpret a shorthand "$foo" to mean
the primary branch head of a tracked remote. clone needs to be
told about this convention as well.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Earlier it did not grok the 0{40} SHA1 very well, but what it
needed to do was to find the shortest 0{N} that is not used as a
valid object name to be consistent with the way names of valid
objects are abbreviated. This makes some users simpler.
Signed-off-by: Junio C Hamano <junkio@cox.net>
We probably thought anybody who does more than 9 parents in an
Octopus is insane when this was initially done, but there is no
inherent reason to limit the number of independent topic
branches that happen to mature at the same time.
Our commit-tree allows up to 16 already, so at least we should
prepare to handle what we can produce, if only to be consistent.
Signed-off-by: Junio C Hamano <junkio@cox.net>
The minimum length of abbreviated object name was hardcoded in
different places to be 4, risking inconsistencies in the future.
Also there were three different "default abbreviation
precision". Use two C preprocessor symbols to clean up this
mess.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When I show transcripts to explain how something works, I often
find myself hand-editing the diff-raw output to shorten various
object names in the output.
This adds --abbrev option to the diff family, which shortens
diff-raw output and diff-tree commit id headers.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This removes the misguided attempt to refuse processing a branch
name xyzzy and insist it to be given as either heads/xyzzy or
tags/xyzzy when a tag xyzzy exists. There was no reason to do
so --- the search order was predictable and well defined, so if
the user says xyzzy we should have taken the tag xyzzy in such a
case without complaining.
This incidentally fixes another subtle bug related to this. If
such a duplicate branch/tag name happened to be a unique valid
prefix of an existing commit object name (say, "beef"), we did
not take the tag "beef" but after complaining used the commit
object whose name started with beef.
Another problem this fixes while introducing some confusion is
that there is no longer a reason to forbid a branch name HEAD
anymore. In other words, now "git pull . ref1:HEAD" would work
as expected, once we revert "We do not like HEAD branch" patch.
It creates "HEAD" branch under ${GIT_DIR-.git}/refs/heads (or
fast-forwards if already exists) using the tip of ref1 branch
from the current repository, and merges it into the current
branch.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When .git/refs/heads/frotz and .git/refs/tags/frotz existed, and
the object name stored in .git/refs/heads/frotz were corrupt, we
ended up picking tags/frotz without complaining. Worse yet, if
the corrupt .git/refs/heads/frotz was more than 40 bytes and
began with hexadecimal characters, it silently overwritten the
initial part of the returned result.
This commit adds a couple of tests to demonstrate these cases,
with a fix.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When both heads/foo and tags/foo exist, get_sha1_basic("foo")
picked up the tag without complaining, which is quite confusing.
Make sure we require unambiguous form, "heads/foo" or "tags/foo"
in such cases.
Signed-off-by: Junio C Hamano <junkio@cox.net>
One caller of deref_tag() was not careful enough to make sure
what deref_tag() returned was not NULL (i.e. we found a tag
object that points at an object we do not have). Fix it, and
warn about refs that point at such an incomplete tag where
needed.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This does two things:
- we don't allow "." and ".." as components of a refname. Thus get_sha1()
will not accept "./refname" as being the same as "refname" any more.
- git-rev-parse stops doing revision translation after seeing a pathname,
to match the brhaviour of all the tools (once we see a pathname,
everything else will also be parsed as a pathname).
Basically, if you did
git log *
and "gitk" was somewhere in the "*", we don't want to replace the filename
"gitk" with the SHA1 of the branch with the same name.
Of course, if there is any change of ambiguity, you should always use "--"
to make it explicit what are filenames and what are revisions, but this
makes the normal cases sane. The refname rule also means that instead of
the "--", you can do the same thing we're used to doing with filenames
that start with a slash: use "./filename" instead, and now it's a
filename, not an option (and not a revision).
So "git log ./*.c" is now actually a perfectly valid thing to do, even if
the first C-file might have the same name as a branch.
Trivial test:
git-rev-parse gitk ./gitk gitk
should output something like
9843c3074d
./gitk
gitk
where the "./gitk" isn't seen as a revision, and the second "gitk" is a
filename simply because we've seen filenames already, and thus stopped
doing revision parsing.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Martin Langhoff noticed that ref^0 barfed correctly when we did not
have the commit in a broken repository, but ref^{commit} didn't.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Existing "tagname^0" notation means "dereference tag zero or more
times until you cannot dereference it anymore, and make sure it is a
commit -- otherwise barf". But tags do not necessarily reference
commit objects.
This commit introduces a bit more generalized notation, "ref^{type}".
Existing "ref^0" is a shorthand for "ref^{commit}". If the type
is empty, it just dereferences tags until it hits a non-tag object.
With this, "git-rev-parse --verify 'junio-gpg-pub^{}'" shows the blob
object name -- there is no need to manually read the tag object and
find out the object name anymore.
"git-rev-parse --verify 'HEAD^{tree}'" can be used to find out the
tree object name of the HEAD commit.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Existing "tagname^0" notation means "dereference tag zero or more
times until you cannot dereference it anymore, and make sure it is a
commit -- otherwise barf". But tags do not necessarily reference
commit objects.
This commit introduces a bit more generalized notation, "ref^{type}".
Existing "ref^0" is a shorthand for "ref^{commit}". If the type
is empty, it just dereferences tags until it hits a non-tag object.
With this, "git-rev-parse --verify 'junio-gpg-pub^{}'" shows the blob
object name -- there is no need to manually read the tag object and
find out the object name anymore.
"git-rev-parse --verify 'HEAD^{tree}'" can be used to find out the
tree object name of the HEAD commit.
Signed-off-by: Junio C Hamano <junkio@cox.net>
git-show-branch acquires two new options. --sha1-name to name
commits using the unique prefix of their object names, and
--no-name to not to show names at all.
This was outlined in <7vk6gpyuyr.fsf@assigned-by-dhcp.cox.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
The earlier fix incorrectly dropped the code the original had to
ensure the found SHA1 is at least unique within the same pack.
Restore the check.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Unlike cases where "no such object exists", the case where specified
prefix is ambiguous would confuse the user if we say "no such commit"
or such. Give an extra error message from the uniqueness check if
there are more than one objects that match the given prefix.
Signed-off-by: Junio C Hamano <junkio@cox.net>
The original code did not even check alternates, and was confused if
an unpacked object was uniquely found when there was another object
that shares the same prefix in the pack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This extends the ref reading to understand a "symbolic ref": a ref file
that starts with "ref: " and points to another ref file, and thus
introduces the notion of ref aliases.
This is in preparation of allowing HEAD to eventually not be a symlink,
but one of these symbolic refs instead.
[jc: Linus originally required the prefix to be "ref: " five bytes
and nothing else, but I changed it to allow and strip any number of
leading whitespaces to match what update-ref.c does.]
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
get_sha1() would not do sha1 completion of short SHA1's when they were
part of a more complex expression. So doing
git-rev-parse 727132834e6be48a93c1bd6458a29d474ce7d5d5^
would work, and return 87c6aeb4ef. But using
the shorthand version
git-rev-list 72713^
wouldn't work.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
The new notation is a short-hand for <name> followed by <num>
caret ('^') characters. E.g. "master~4" is the fourth
generation ancestor of the current "master" branch head,
following the first parents; same as "master^^^^" but a bit
more readable.
This will be used in the updated "git show-branch" command.
Signed-off-by: Junio C Hamano <junkio@cox.net>
I think Linus did a cut & paste from an early JIT code while
developing the current extended SHA1 notation, and left it there as a
courtesy, but the directory does not deserve to be treated any more
specially than, say, .git/refs/bisect.
If the subdirectories under .git/refs proliferate, we may want to
switch to scanning that hierarchy at runtime, instead of the current
hard-coded set, although I think that would be overkill.
Signed-off-by: Junio C Hamano <junkio@cox.net>
From nobody Mon Sep 17 00:00:00 2001
Subject: [PATCH] Add a new extended SHA1 syntax <name>:<num>
From: Junio C Hamano <junkio@cox.net>
Date: 1124617434 -0700
The new notation is a short-hand for <name> followed by <num>
caret ('^') characters. E.g. "master:4" is the fourth
generation ancestor of the current "master" branch head,
following the first parents; same as "master^^^^" but a bit more
readable.
This will be used in the updated "git show-branch" command.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
sha1_name.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
d5098ce769da46df6d45dc8f41b06dd758fdaea7
diff --git a/sha1_name.c b/sha1_name.c
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -191,9 +191,29 @@ static int get_parent(const char *name,
return -1;
}
+static int get_nth_ancestor(const char *name, int len,
+ unsigned char *result, int generation)
+{
+ unsigned char sha1[20];
+ int ret = get_sha1_1(name, len, sha1);
+ if (ret)
+ return ret;
+
+ while (generation--) {
+ struct commit *commit = lookup_commit_reference(sha1);
+
+ if (!commit || parse_commit(commit) || !commit->parents)
+ return -1;
+ memcpy(sha1, commit->parents->item->object.sha1, 20);
+ }
+ memcpy(result, sha1, 20);
+ return 0;
+}
+
static int get_sha1_1(const char *name, int len, unsigned char *sha1)
{
int parent, ret;
+ const char *cp;
/* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
if (len > 2 && name[len-2] == '^' &&
@@ -210,6 +230,27 @@ static int get_sha1_1(const char *name,
if (parent >= 0)
return get_parent(name, len, sha1, parent);
+ /* name:3 is name^^^,
+ * name:12 is name^^^^^^^^^^^^, and
+ * name: is name
+ */
+ parent = 0;
+ for (cp = name + len - 1; name <= cp; cp--) {
+ int ch = *cp;
+ if ('0' <= ch && ch <= '9')
+ continue;
+ if (ch != ':')
+ parent = -1;
+ break;
+ }
+ if (!parent && *cp == ':') {
+ int len1 = cp - name;
+ cp++;
+ while (cp < name + len)
+ parent = parent * 10 + *cp++ - '0';
+ return get_nth_ancestor(name, len1, sha1, parent);
+ }
+
ret = get_sha1_basic(name, len, sha1);
if (!ret)
return 0;
The "get_sha1_hex()" function is designed to work with SHA1 hex strings
that may be followed by arbitrary crud. However, that's not acceptable for
"get_sha1()" which is used for command line arguments etc: we don't want
to silently allow random characters after the end of the SHA1.
So verify that the hex string is all we have.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
You can resolve a tag, and it does the right thing except that it might
end up writing the tag itself into the resulting HEAD, which will confuse
subsequent operations no end.
This makes sure that when we resolve two heads, we will have turned them
into proper commits before we start acting on them.
This also fixes the parsing of "treeish^0", which would incorrectly
resolve to "treeish" instead of causing an error.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>