Commit Graph

83 Commits

Author SHA1 Message Date
Junio C Hamano
73b0e5af9d get_sha1(): :path and :[0-3]:path to extract from index.
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>
2006-04-30 17:55:34 -07:00
Junio C Hamano
4dcff634e6 get_tree_entry(): make it available from tree-walk
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-19 14:05:47 -07:00
Junio C Hamano
f3ab49db1b sha1_name.c: no need to include diff.h; tree-walk.h will do.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-19 11:56:53 -07:00
Junio C Hamano
041a7308de sha1_name.c: prepare to make get_tree_entry() reusable from others.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-04-19 11:56:07 -07:00
Linus Torvalds
5119602a99 get_sha1() shorthands for blob/tree objects
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>
2006-04-18 21:52:41 -07:00
Junio C Hamano
84a9b58c42 sha1_name: warning ambiguous refs.
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>
2006-03-23 23:41:18 -08:00
Junio C Hamano
c51d13692d get_sha1_basic(): try refs/... and finally refs/remotes/$foo/HEAD
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>
2006-03-21 01:42:04 -08:00
Junio C Hamano
2f8acdb38e core.warnambiguousrefs: warns when "name" is used and both "name" branch and tag exists.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-03-20 23:34:17 -08:00
Junio C Hamano
297a1aadbe find_unique_abbrev() simplification.
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>
2006-02-10 01:51:12 -08:00
Junio C Hamano
0601dbe178 get_sha1_1: allow octopus^12 to be properly parsed.
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>
2006-02-02 23:49:44 -08:00
Junio C Hamano
46a6c2620b abbrev cleanup: use symbolic constants
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>
2006-01-28 00:09:38 -08:00
Uwe Zeisberger
e974c9ab03 Use symbolic name SHORT_NAME_AMBIGUOUS as error return value
Signed-off-by: Uwe Zeisberger <zeisberg@informatik.uni-freiburg.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-01-26 18:13:54 -08:00
Junio C Hamano
47dd0d595d diff: --abbrev option
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>
2005-12-19 18:32:44 -08:00
Junio C Hamano
c054d64e87 Revert "get_sha1_basic(): corner case ambiguity fix"
This reverts 6677c4665a commit.

The misguided disambiguation has been reverted, so there is no point
testing that misfeature.
2005-12-17 23:10:56 -08:00
Junio C Hamano
011fbc7f07 Remove misguided branch disambiguation.
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>
2005-12-17 23:10:56 -08:00
Junio C Hamano
6677c4665a get_sha1_basic(): corner case ambiguity fix
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>
2005-12-15 12:54:00 -08:00
Junio C Hamano
924215024c Make sure heads/foo and tags/foo do not confuse things.
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>
2005-11-21 00:43:12 -08:00
Junio C Hamano
9534f40bc4 Be careful when dereferencing tags.
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>
2005-11-02 16:50:58 -08:00
Linus Torvalds
af13cdf298 Be more careful about reference parsing
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>
2005-10-28 14:25:05 -07:00
Junio C Hamano
6e1c6c103c Make sure we barf on ref^{type} failure.
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>
2005-10-19 22:49:31 -07:00
Junio C Hamano
5385f52da8 Introduce notation "ref^{type}".
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>
2005-10-15 11:23:40 -07:00
Junio C Hamano
013f276eb7 show-branch: optionally use unique prefix as name.
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>
2005-10-11 15:22:48 -07:00
Junio C Hamano
0bc4589020 Make sure get_sha1 does not accept ambiguous sha1 prefix (again).
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>
2005-10-03 18:50:06 -07:00
Junio C Hamano
5a82b4fb3e Error message from get_sha1() on ambiguous short SHA1.
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>
2005-10-03 00:36:13 -07:00
Junio C Hamano
99a19b4302 Make sure get_sha1 does not accept ambiguous sha1 prefix.
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>
2005-10-02 21:40:51 -07:00
Linus Torvalds
ca8db1424d [PATCH] Allow reading "symbolic refs" that point to other refs
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>
2005-10-01 23:19:32 -07:00
Linus Torvalds
af61c6e008 Fix extended short SHA1 name completion
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>
2005-09-20 15:04:19 -07:00
Junio C Hamano
4f7599ac25 [PATCH] Add a new extended SHA1 syntax <name>~<num>
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>
2005-08-22 18:34:09 -07:00
Junio C Hamano
1dfcfbce2d [PATCH] sha1_name: do not accept .git/refs/snap/.
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;
2005-08-21 03:52:55 -07:00
Linus Torvalds
3c3852e33b [PATCH] Make get_sha1_basic() more careful
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>
2005-08-13 18:28:51 -07:00
Linus Torvalds
02a4a32c2d [PATCH] Make sure git-resolve-script always works on commits
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>
2005-08-13 18:28:50 -07:00
Johannes Schindelin
ef0bd2e6e6 [PATCH] Fix git-rev-parse's parent handling
git-rev-parse HEAD^1 would fail, because of an off-by-one bug (but HEAD^
would yield the expected result). Also, when the parent does not exist, do
not silently return an incorrect SHA1. Of course, this no longer applies
to git-rev-parse alone, but every user of get_sha1().

While at it, add a test.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-10 10:22:49 -07:00
Junio C Hamano
9938af6a85 Update get_sha1() to grok extended format.
Everybody envies rev-parse, who is the only one that can grok
the extended sha1 format.  Move the get_extended_sha1() out of
rev-parse, rename it to get_sha1() and make it available to
everybody else.

The one I posted earlier to the list had one bug where it did
not handle a name that ends with a digit correctly (it
incorrectly tried the "Nth parent" path).  This commit fixes it.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-05 00:51:07 -07:00