Commit graph

30 commits

Author SHA1 Message Date
Linus Torvalds 3c07b1d194 git's rev-parse.c function show_datestring presumes gnu date
Ok. This is the insane patch to do this.

It really isn't very careful, and the reason I call it "approxidate()"
will become obvious when you look at the code. It is very liberal in what
it accepts, to the point where sometimes the results may not make a whole
lot of sense.

It accepts "last week" as a date string, by virtue of "last" parsing as
the number 1, and it totally ignoring superfluous fluff like "ago", so
"last week" ends up being exactly the same thing as "1 week ago". Fine so
far.

It has strange side effects: "last december" will actually parse as "Dec
1", which actually _does_ turn out right, because it will then notice that
it's not December yet, so it will decide that you must be talking about a
date last year. So it actually gets it right, but it's kind of for the
"wrong" reasons.

It also accepts the numbers 1..10 in string format ("one" .. "ten"), so
you can do "ten weeks ago" or "ten hours ago" and it will do the right
thing.

But it will do some really strange thigns too: the string "this will last
forever", will not recognize anyting but "last", which is recognized as
"1", which since it doesn't understand anything else it will think is the
day of the month. So if you do

	gitk --since="this will last forever"

the date will actually parse as the first day of the current month.

And it will parse the string "now" as "now", but only because it doesn't
understand it at all, and it makes everything relative to "now".

Similarly, it doesn't actually parse the "ago" or "from now", so "2 weeks
ago" is exactly the same as "2 weeks from now". It's the current date
minus 14 days.

But hey, it's probably better (and certainly faster) than depending on GNU
date. So now you can portably do things like

	gitk --since="two weeks and three days ago"
	git log --since="July 5"
	git-whatchanged --since="10 hours ago"
	git log --since="last october"

and it will actually do exactly what you thought it would do (I think). It
will count 17 days backwards, and it will do so even if you don't have GNU
date installed.

(I don't do "last monday" or similar yet, but I can extend it to that too
if people want).

It was kind of fun trying to write code that uses such totally relaxed
"understanding" of dates yet tries to get it right for the trivial cases.
The result should be mixed with a few strange preprocessor tricks, and be
submitted for the IOCCC ;)

Feel free to try it out, and see how many strange dates it gets right. Or
wrong.

And if you find some interesting (and valid - not "interesting" as in
"strange", but "interesting" as in "I'd be interested in actually doing
this) thing it gets wrong - usually by not understanding it and silently
just doing some strange things - please holler.

Now, as usual this certainly hasn't been getting a lot of testing. But my
code always works, no?

		Linus

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-11-16 23:54:37 -08:00
Junio C Hamano 5a83f3be24 Update git-rev-list options list in rev-parse.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-30 17:28:02 -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
Linus Torvalds 7b34c2fae0 git-rev-list: make --dense the default (and introduce "--sparse")
This actually does three things:

 - make "--dense" the default for git-rev-list. Since dense is a no-op if
   no filenames are given, this doesn't actually change any historical
   behaviour, but it's logically the right default (if we want to prune on
   filenames, do it fully. The sparse "merge-only" thing may be useful,
   but it's not what you'd normally expect)

 - make "git-rev-parse" show the default revision control before it shows
   any pathnames.

   This was a real bug, but nobody would ever have noticed, because
   the default thing tends to only make sense for git-rev-list, and
   git-rev-list didn't use to take pathnames.

 - it changes "git-rev-list" to match the other commands that take a mix
   of revisions and filenames - it no longer requires the "--" before
   filenames (although you still need to do it if a filename could be
   confused with a revision name, eg "gitk" in the git archive)

This all just makes for much more pleasant and obvous usage. Just doing a

	gitk t/

does the obvious thing: it will show the history as it concerns the "t/"
subdirectory.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-26 16:49:38 -07:00
Linus Torvalds a08b650594 git-rev-parse: pass on "--" flag when required
If rev-parse output includes both flags and files, we should pass on any
"--" marker we see, so that the end result can also tell the difference
between a flag and a filename that begins with '-'.

[jc: merged a later one liner updates from Linus]

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-20 22:32:07 -07:00
Linus Torvalds 7a3dd472ad Avoid ambiguity between refname and filename in rev-parse
Although it really is very convenient, not requiring explicit
'-r' option to name revs is sometimes ambiguous.

Usually we allow a "--" to say where a filename starts when it
_is_ ambiguous.  However, we fail that at times. In particular,
git-rev-parse fails it.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-18 00:16:45 -07:00
Junio C Hamano e091eb9325 upload-pack: Do not choke on too many heads request.
Cloning from a repository with more than 256 refs (heads and tags
included) will choke, because upload-pack has a built-in limit of
feeding not more than MAX_NEEDS (currently 256) heads to underlying
git-rev-list.  This is a problem when cloning a repository with many
tags, like http://www.linux-mips.org/pub/scm/linux.git, which has 290+
tags.

This commit introduces a new flag, --all, to git-rev-list, to include
all refs in the repository.  Updated upload-pack detects requests that
ask more than MAX_NEEDS refs, and sends everything back instead.

We may probably want to tweak the definitions of MAX_NEEDS and
MAX_HAS, but that is a separate topic.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-10-05 14:49:54 -07:00
Linus Torvalds c1babb1d65 [PATCH] Teach "git-rev-parse" about date-based cut-offs
This adds the options "--since=date" and "--before=date" to git-rev-parse,
which knows how to translate them into seconds since the epoch for
git-rev-list.

With this, you can do

	git log --since="2 weeks ago"

or

	git log --until=yesterday

to show the commits that have happened in the last two weeks or are
older than 24 hours, respectively.

The flags "--after=" and "--before" are synonyms for --since and --until,
and you can combine them, so

	git log --after="Aug 5" --before="Aug 10"

is a valid (but strange) thing to do.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-20 18:10:32 -07:00
Linus Torvalds a8783eeb79 [PATCH] Add "--git-dir" flag to git-rev-parse
Especially when you're deep inside the git repository, it's not all that
trivial for scripts to figure out where GIT_DIR is if it isn't set.

So add a flag to git-rev-parse to show where it is, since it will have
figured it out anyway.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-09-18 14:18:34 -07:00
Junio C Hamano 4866ccf0f4 Rationalize output selection in rev-parse.
Earlier rounds broke 'whatchanged -p'.  In attempting to fix this,
make two axis of output selection in rev-parse orthogonal:

  --revs-only	tells it not to output things that are not revisions nor
		flags that rev-list would take.
  --no-revs	tells it not to output things that are revisions or
		flags that rev-list would take.
  --flags	tells it not to output parameters that do not start with
		a '-'.
  --no-flags	tells it not to output parameters that starts with a '-'.

So for example 'rev-parse --no-revs -p arch/i386' would yield '-p arch/i386',
while 'rev-parse --no-revs --flags -p archi/i386' would give just '-p'.

Also the meaning of --verify has been made stronger.  It now rejects
anything but a single valid rev argument.  Earlier it passed some flags
through without complaining.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-24 14:30:04 -07:00
Linus Torvalds 0360e99d06 [PATCH] Fix git-rev-parse --default and --flags handling
This makes the argument to --default and any --flags arguments should up 
correctly, and makes "--" together with --flags act sanely.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-23 12:42:58 -07:00
Junio C Hamano 30b96fcef1 Add --symbolic flag to git-rev-parse.
This is most useful with --all, --revs-only, --no-flags and --verify.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-17 12:11:36 -07:00
Linus Torvalds d288a70030 [PATCH] Make "git diff" work inside relative subdirectories
We always show the diff as an absolute path, but pathnames to diff are
taken relative to the current working directory (and if no pathnames are
given, the default ends up being all of the current working directory).

Note that "../xyz" also works, so you can do

	cd linux/drivers/char
	git diff ../block

and it will generate a diff of the linux/drivers/block changes.

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-16 18:47:22 -07:00
Junio C Hamano 5ccfb758b0 Update rev-parse flags list.
I haven't audited the rev-parse users, but I am having a feeling
that many of them would choke when they expect a couple of SHA1
object names and malicious user feeds them "--max-count=6" or
somesuch to shoot himself in the foot.  Anyway, this adds a
couple of missing parameters that affect the list of revs to be
returned from rev-list, not the flags that affect how they are
presented by rev-list.  I think that is the intention, but I am
not quite sure.

Signed-off-by: Junio C Hamano <junkio@cox.net>
2005-08-09 22:28:21 -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
Junio C Hamano 5bb2c65aba [PATCH] Help scripts that use git-rev-parse to grok args with SP/TAB/LF
The git-rev-parse command uses LF to separate each argument it
parses, so its users at least need to set IFS to LF to be able
to handle filenames with embedded SPs and TABs.  Some commands,
however, can take and do expect arguments with embedded LF,
notably, "-S" (pickaxe) of diff family, so even this workaround
does not work for them.

When --sq flag to git-rev-parse is given, instead of showing one
argument per line, it outputs arguments quoted for consumption
with "eval" by the caller, to remedy this situation.

As an example, this patch converts git-whatchanged to use this
new feature.

Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-07-22 20:34:16 -07:00
Linus Torvalds 79162bb8ad git-rev-parse: Allow a "zeroth" parent of a commit - the commit itself.
This sounds nonsensical, but it's useful to make sure that the result is
a commit.

For example, "git-rev-parse v2.6.12" will return the _tag_ object for
v2.6.12, but "git-rev-parse v2.6.12^0" will return the _commit_ object
associated with that tag (and v2.6.12^1 will return the first parent).

Also, since the "parent" code will actually parse the commit, this,
together with the "--verify" flag, will verify not only that the result
is a single SHA1, but will also have verified that it's a proper commit
that we can see.
2005-07-11 18:27:25 -07:00
Linus Torvalds f79b65aa65 Add "--flags" and "--no-flags" arguments to git-rev-parse
The scripts that use this (notably "git diff") will want to split up
flags and file arguments.
2005-07-06 10:08:08 -07:00
Linus Torvalds 671fe4bb20 git-rev-parse: support show sha1 names for pack entries
This is actually subtly wrong.  If a short match is found in the object
directory, but would _also_ match another SHA1 ID in a pack (or it shows
in one pack but not another), we'll never have done the pack lookup, and
we think it's unique.

I can't find it in myself to care.  You really want to use enough of a
SHA1 that there is never any ambiguity.
2005-07-03 21:01:11 -07:00
Linus Torvalds 5736bef18c Make git-rev-parse support cogito-style "short hex names"
Currently only for unpacked objects, but the infrastructure
is there to do it for packed objects too.
2005-07-03 20:27:06 -07:00
Linus Torvalds 960bba0d8c Add "--all" flag to rev-parse that shows all refs
And make git-rev-list just silently ignore non-commit refs if we're not
asking for all objects.
2005-07-03 13:07:52 -07:00
Linus Torvalds 042a4ed7c5 git-rev-parse: add "--not" flag to mark subsequent heads negative
If you have two lists of heads, and you want to see ones reachable from
list $a but not from list $b, just do

	git-rev-list $(git-rev-parse $a --not $b)

which is useful for both bisecting (where "b" would be the list of known
good revisions, and "a" would be the latest found bad head) and for just
seeing what the difference between two sets of heads are if you want to
generate a pack-file for the difference.
2005-06-26 11:34:30 -07:00
Linus Torvalds 023d66ed7b git-rev-parse: re-organize and be more careful
Output default revisions as their hex SHA1 names to be consistent.

Add "--verify" flag that verifies that we output a single ref and not
more (and disables ref arguments).
2005-06-24 10:12:55 -07:00
Linus Torvalds 218e441daf Change parent syntax to "xyz^" instead of "xyz.p"
The ".pN" thing might be a common ending of a tag, and in
contrast, ^ already is a special character for revisions
so use that instead.
2005-06-20 21:06:47 -07:00
Linus Torvalds a8be83fe00 Make rev-parse understand "extended sha1" syntax
You can say "HEAD.p" for the "parent of HEAD". It nests, so

	HEAD.p2.p

means parent of second parent of HEAD (which obviously depends
on HEAD being a merge).
2005-06-20 20:28:09 -07:00
Linus Torvalds 9d73fad4ca git-rev-parse: flush "default" head when encountering something unexpected
The unexpected thing is likely a pathname, we need the default for that
too.
2005-06-20 16:14:13 -07:00
Linus Torvalds 800644c5cb git-rev-parse: parse ".." before simple SHA1's
This fixes "<hexsha1>..*", since get_sha1() will happily ignore any
garbage at the end and thus we never got to the ".." check before.
2005-06-20 08:29:13 -07:00
Linus Torvalds 921d865ea2 Teach git-rev-parse about revision-specifying arguments
Things like "--max-count=xxx" are "rev-only".
2005-06-13 11:14:20 -07:00
Linus Torvalds 8ebb018402 git-rev-parse: split "revs" and "non-revs"
Sometimes we only want to output revisions, and sometimes we want to
only see the stuff that wasn't revisions.  Teach git-rev-parse to
understand the "--revs-only" and "--no-revs" flags.
2005-06-13 10:21:11 -07:00
Linus Torvalds 178cb24338 Add 'git-rev-parse' helper script
It's an incredibly cheesy helper that changes human-readable revision
arguments into the git-rev-list argument format.

You can use it to do something like this:

	git-rev-list --pretty $(git-rev-parse --default HEAD "$@")

which is what git-log-script will become. Here git-rev-parse will
then allow you to use arguments like "v2.6.12-rc5.." or similar
human-readable ranges.

It's really quite stupid: "a..b" will be converted into "a" and "^b" if
"a" and "b" are valid object pointers.  And the "--default" case will be
used if nothing but flags have been seen, so that you can default to a
certain argument if there are no other ranges.
2005-06-13 10:06:50 -07:00