Git development
 help / color / mirror / Atom feed
* [PATCH] describe: load refnames before calling describe()
From: René Scharfe @ 2009-10-17 16:30 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano, Shawn O. Pearce

Get rid of the static variable that was used to prevent loading all
the refnames multiple times by moving that code out of describe(),
simply making sure it is only run once that way.

Also change the error message that is shown in case no refnames are
found to not include a hash any more, as the error condition is not
specific to any particular revision.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 builtin-describe.c |   13 ++++---------
 1 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/builtin-describe.c b/builtin-describe.c
index df67a73..2dcfd3d 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -180,7 +180,6 @@ static void describe(const char *arg, int last_one)
 	unsigned char sha1[20];
 	struct commit *cmit, *gave_up_on = NULL;
 	struct commit_list *list;
-	static int initialized = 0;
 	struct commit_name *n;
 	struct possible_tag all_matches[MAX_TAGS];
 	unsigned int match_cnt = 0, annotated_cnt = 0, cur_match;
@@ -192,14 +191,6 @@ static void describe(const char *arg, int last_one)
 	if (!cmit)
 		die("%s is not a valid '%s' object", arg, commit_type);
 
-	if (!initialized) {
-		initialized = 1;
-		for_each_ref(get_name, NULL);
-	}
-
-	if (!found_names)
-		die("cannot describe '%s'", sha1_to_hex(sha1));
-
 	n = cmit->util;
 	if (n) {
 		/*
@@ -359,6 +350,10 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 		return cmd_name_rev(i + argc, args, prefix);
 	}
 
+	for_each_ref(get_name, NULL);
+	if (!found_names)
+		die("No names found, cannot describe anything.");
+
 	if (argc == 0) {
 		describe("HEAD", 1);
 	} else {
-- 
1.6.5

^ permalink raw reply related

* Re: Introduction and Wikipedia and Git Blame
From: jamesmikedupont @ 2009-10-17 16:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <ee9cc730910162350p250b8afak767b0626bede34e4@mail.gmail.com>

I have done a workaround hack,
today I attempted to hack the blame code but I need to do more
research, it did not work.

But I did get a new version of the import script running and word
level blame going.

http://fmtyewtk.blogspot.com/2009/10/mediawiki-git-word-level-blaming-one.html

Next step is ready :

1. I have a single script that will pull a given article and check in
the revisions into git,
it is not perfect, but works.

http://bazaar.launchpad.net/~jamesmikedupont/+junk/wikiatransfer/revision/8
you run it like this,from inside a git repo :

perl GetRevisions.pl "Article_Name"

git blame Article_Name/Article.xml
git push origin master

The code that splits up the line is in Process File, this splits all
spaces into newlines.
that way we get a word level blame.

     if ($insidetext)
     {
  ## split all lines on the space
  s/(\ )/\\\n/g;


  print OUT  $_;
     }


The Article is here:
http://github.com/h4ck3rm1k3/KosovoWikipedia/blob/master/Wiki/2008_Kosovo_declaration_of_independence/article.xml


here are the blame results.
http://github.com/h4ck3rm1k3/KosovoWikipedia/blob/master/Wiki/2008_Kosovo_declaration_of_independence/wordblame.txt


Problem is that github does not like this amount of processor power
begin used and kills the process, you can do a local git blame.

Now we have the tool to easily create a repository from wikipedia, or
any other export enabled mediawiki.

mike


On Sat, Oct 17, 2009 at 8:50 AM, jamesmikedupont@googlemail.com
<jamesmikedupont@googlemail.com> wrote:
> Thank you very much for your input and advice,
> I have a lot of learn about this great tool.
> I am working on learning how the existing blame tool runs now.
> Will report back when I have some code.
> mike
>
> On Sat, Oct 17, 2009 at 1:25 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> "jamesmikedupont@googlemail.com" <jamesmikedupont@googlemail.com> writes:
>>
>>> What do you think of my idea to create blames along a specific user
>>> defined byte positions ?
>>
>> Overly complicated and not enough time for _review_.  If you are blaming
>> one-byte (or one-char) per line, wouldn't it be enough to consider the
>> line number in the output as byte (or char) position when reconstituting
>> the original text?
>>
>

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Björn Steinbrink @ 2009-10-17 17:04 UTC (permalink / raw)
  To: Julian Phillips
  Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
	Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <alpine.LNX.2.00.0910171606180.6644@reaper.quantumfyre.co.uk>

On 2009.10.17 16:15:13 +0100, Julian Phillips wrote:
> On Fri, 16 Oct 2009, Nicolas Pitre wrote:
> 
> >On Fri, 16 Oct 2009, Julian Phillips wrote:
> >
> >>My interest in this thread is solely that it might provide a mechanism to find
> >>out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.
> >
> >Try this:
> >
> >$ git checkout v1.5.5
> >Note: moving to 'v1.5.5' which isn't a local branch
> >If you want to create a new branch from this checkout, you may do so
> >(now or later) by using -b with the checkout command again. Example:
> > git checkout -b <new_branch_name>
> >HEAD is now at 1d2375d... GIT 1.5.5
> >
> >[look around, and then ...]
> >
> >$ git checkout HEAD~2
> >Previous HEAD position was 1d2375d... GIT 1.5.5
> >HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path
> >
> >[go out for lunch ... and forget what this was about.]
> >
> >$ git reflog -3
> >f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2
> >1d2375d HEAD@{1}: checkout: moving from master to v1.5.5
> >c274db7 HEAD@{2}: pull : Fast forward
> >
> >Here I have all the information to see what I did, and from what state.
> >I even know that I did a pull on the master branch before moving away
> >from it.  The -3 limits the log to 3 entries.  With no limit you get it
> >all in your default pager.
> >
> >So there is no need for another mechanism to find out what tag was
> >actually checked out -- you have it all already.
> 
> What I want is a way for my build process to reliably know what
> branch or tag is currently being built.  "git symbolic-ref HEAD"
> will give me the branch name, but doesn't work for tags.  "git
> describe" will find _a_ tag, but I can't tell if it's actually the
> one checked out.

Do you have multiple (annotated) tags for the same commit? Otherwise, I
don't see why "git describe HEAD" should print the wrong one. If there's
a tag that can be resolved to the same commit that HEAD can be resolved,
then "git describe HEAD" must output that one. Otherwise, that'd be a
clear bug to me.

Björn

^ permalink raw reply

* Re: [PATCH v3 1/5] Refactor pretty_print_commit arguments into a struct
From: Junio C Hamano @ 2009-10-17 17:05 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Jeff King, Jef Driesen, Nanako Shiraishi, git
In-Reply-To: <9d3d0f0a6126afc86689138adf58ac7a12c43858.1255701207.git.trast@student.ethz.ch>

Thomas Rast <trast@student.ethz.ch> writes:

> pretty_print_commit() has a bunch of rarely-used arguments, and
> introducing more of them requires yet another update of all the call
> sites.  Refactor most of them into a struct to make future extensions
> easier.
>
> The ones that stay "plain" arguments were chosen on the grounds that
> all callers put real arguments there, whereas some callers have 0/NULL
> for all arguments that were factored into the struct.
>
> We declare the struct 'const' to ensure none of the callers are bitten
> by the changed (no longer call-by-value) semantics.
>
> Signed-off-by: Thomas Rast <trast@student.ethz.ch>

Good idea, a slightly sloppy/careless execution.

The existing calls to format_commit_message() often take DATE_NORMAL to
its "enum date_mode dmode" argument, and you replaced it with a pointer to
a struct.  DATE_NORMAL happens to be "0" and the compiler does not catch
calls you forgot to convert in this patch.

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD  was
From: James Pickens @ 2009-10-17 17:07 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Björn Steinbrink, Julian Phillips, Daniel Barkalow,
	Jeff King, Nicolas Pitre, Jay Soffian, git
In-Reply-To: <7vaazqcry5.fsf@alter.siamese.dyndns.org>

On Sat, Oct 17, 2009, Junio C Hamano <gitster@pobox.com> wrote:
> As I already said many times (here and elsewhere), "up" is an inferior and
> more dangerous model we would be better off not following if we can.

I agree that the "up" model is inferior, but I have to say, "up" is one of the
most common things my users ask about.  It is very common for users to have some
work in progress that they aren't ready to commit, and they want to get up to
date with the latest code from the central repository.  Most of the time, they
haven't modified any files that have also been modified upstream, so all they
need is "git pull".  But once in a while, they will have modified the same file,
and the pull will be rejected, and they don't know what to do.

These are not sophisticated users, so telling them to commit first, then pull,
and rebase later on to clean up the history (since the work they committed
wasn't finished) is no good.  They don't care to preserve their exact state and
just want to get up to date with the central repo.

If they ask me what to do, I tell them that if they're ready to commit, do so,
otherwise use 'git stash; git pull; git stash pop'.  To a typical user, this
looks like Git is inferior since it requires 3 commands to do what only takes 1
command in CVS/SVN.  One of my users didn't ask, and I later found out that he
had been doing this:

$ git pull ;# rejected due to modifications in file1
$ mv file1 file1.bak
$ git checkout HEAD file1
$ git pull ;# rejected due to modifications in file2
$ mv file2 file2.bak
$ git checkout HEAD file2
$ git pull ;# ok
<manually merge file1.bak with file1>
<manually merge file2.bak with file2>

So I think an "scm up" like command is not an unreasonable thing to want.  There
is a valid, and fairly common, use case.  There are ways to get the same result
in Git, but they're cumbersome compared to just typing "scm up".  It shouldn't
be the default, but I think a lot of users would appreciate having it.

James

^ permalink raw reply

* git submodules
From: Steven Noonan @ 2009-10-17 17:15 UTC (permalink / raw)
  To: Git Mailing List; +Cc: crawl-ref-discuss

One of the open source projects I work on (CC'd) recently moved to
git, but we're having some slight problems, and I believe that it's
the fault of git's UI in this case.

We're using git submodules for the contributing libraries. When I
commit changes to those contribs, it correctly shows in the parent
repository that those folders have different revisions than what's
currently committed. However, if someone pulls those changes, it
doesn't automatically update the contribs to match the committed
version. But doing a pull or merge _should_ update the working tree to
match the committed versions. It does with file data, so why not
update the submodules? Especially if the submodule revision matched
the committed version -before- the pull. Why are we forced into using
'git submodule update'?

- Steven

^ permalink raw reply

* Re: git submodules
From: Jakub Narebski @ 2009-10-17 17:27 UTC (permalink / raw)
  To: Steven Noonan; +Cc: Git Mailing List, crawl-ref-discuss
In-Reply-To: <f488382f0910171015j1a6d4d9fg690867154334c514@mail.gmail.com>

Steven Noonan <steven@uplinklabs.net> writes:

> We're using git submodules for the contributing libraries. When I
> commit changes to those contribs, it correctly shows in the parent
> repository that those folders have different revisions than what's
> currently committed. However, if someone pulls those changes, it
> doesn't automatically update the contribs to match the committed
> version. But doing a pull or merge _should_ update the working tree to
> match the committed versions. It does with file data, so why not
> update the submodules? Especially if the submodule revision matched
> the committed version -before- the pull. Why are we forced into using
> 'git submodule update'?

Because you might want not to use most current version of submodule,
so git-pull shouldn't update submodules by default.  And because
git-pull didn't learn --recursive option yet.

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 17:35 UTC (permalink / raw)
  To: Björn Steinbrink
  Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
	Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <20091017170421.GA10490@atjola.homenet>

On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:

> On 2009.10.17 16:15:13 +0100, Julian Phillips wrote:
>> On Fri, 16 Oct 2009, Nicolas Pitre wrote:
>>
>>> On Fri, 16 Oct 2009, Julian Phillips wrote:
>>>
>>>> My interest in this thread is solely that it might provide a mechanism to find
>>>> out which tag was checked out.  So, I'm just chucking in my $0.02 as a user.
>>>
>>> Try this:
>>>
>>> $ git checkout v1.5.5
>>> Note: moving to 'v1.5.5' which isn't a local branch
>>> If you want to create a new branch from this checkout, you may do so
>>> (now or later) by using -b with the checkout command again. Example:
>>> git checkout -b <new_branch_name>
>>> HEAD is now at 1d2375d... GIT 1.5.5
>>>
>>> [look around, and then ...]
>>>
>>> $ git checkout HEAD~2
>>> Previous HEAD position was 1d2375d... GIT 1.5.5
>>> HEAD is now at f61cc48... git-svn: fix following renamed paths when tracking a single path
>>>
>>> [go out for lunch ... and forget what this was about.]
>>>
>>> $ git reflog -3
>>> f61cc48 HEAD@{0}: checkout: moving from 1d2375d... to HEAD~2
>>> 1d2375d HEAD@{1}: checkout: moving from master to v1.5.5
>>> c274db7 HEAD@{2}: pull : Fast forward
>>>
>>> Here I have all the information to see what I did, and from what state.
>>> I even know that I did a pull on the master branch before moving away
>>> from it.  The -3 limits the log to 3 entries.  With no limit you get it
>>> all in your default pager.
>>>
>>> So there is no need for another mechanism to find out what tag was
>>> actually checked out -- you have it all already.
>>
>> What I want is a way for my build process to reliably know what
>> branch or tag is currently being built.  "git symbolic-ref HEAD"
>> will give me the branch name, but doesn't work for tags.  "git
>> describe" will find _a_ tag, but I can't tell if it's actually the
>> one checked out.
>
> Do you have multiple (annotated) tags for the same commit?

Potentially, yes.  Releasing isn't the only thing that requires keeping 
track of things.  It's even possible that the person creating the newer 
tag doesn't yet know that a release tag has been applied if the person 
who applied it hasn't yet pushed it back.

> Otherwise, I don't see why "git describe HEAD" should print the wrong 
> one. If there's a tag that can be resolved to the same commit that HEAD 
> can be resolved, then "git describe HEAD" must output that one. 
> Otherwise, that'd be a clear bug to me.

Oh, definately no bug.  git describe works exactly as expected, the 
problem is that the tag checked out isn't always the latest tag applied to 
that commit.

-- 
Julian

  ---
Jayne: Shee-nio high tech Alliance crap!"
 				--Episode #9, "Ariel"

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Junio C Hamano @ 2009-10-17 17:42 UTC (permalink / raw)
  To: Björn Steinbrink
  Cc: Junio C Hamano, Christoph Bartoschek, git, Daniel Barkalow
In-Reply-To: <20091017081901.GB5474@atjola.homenet>

Björn Steinbrink <B.Steinbrink@gmx.de> writes:

> On 2009.10.17 00:43:31 -0700, Junio C Hamano wrote:
>> Christoph Bartoschek <bartoschek@gmx.de> writes:
>> > Daniel Barkalow wrote:
>> >
>> >> The upshot of the messages should be:
>> >> 
>> >>  $ git checkout origin/master
>> >>  Since you can't actually change "origin/master" yourself, you'll just
>> >>  be sightseeing unless you create a local branch to hold new local work.
>> >> 
>> >>  $ git branch
>> >>  * (not a local branch, but "origin/master")
>> >> 
>> >>  $ git commit
>> >>  You've been sightseeing "origin/master". The commit can't change that
>> >>  value, so your commit isn't held in any branch. If you want to create
>> >>  a branch to hold it, here's how.
>
> [...]
>
>> The second item in the Daniel's transcript above may be an improvement but
>> I think it is a wrong economy to record and show 'but "origin/master"'
>> (which cannot be correct forever and has to be invalidated once the user
>> starts committing or resetting) in the message.
>
> I don't think it's entirely wrong to record that information, git just
> has to know when to invalidate it, possibly requiring the user to really
> detach HEAD.

Isn't it redundant information to begin with?  See $gmane/130527

> git checkout origin/master
> git checkout origin/master~3
> git checkout HEAD^2~5
> git reset --hard HEAD~2
>
> Those commands are all about walking the ancestry of origin/master in
> some way. So it seems reasonable to assume that HEAD is still weakly
> bound to origin/master.

But as "walking" gets longer, the information will become less and less
relevant and at some point it becomes misleading.  I cannot explain why
"let's take pains to maintain and carefully invalidate an extra piece of
redundant information so that we can show information the end user
shouldn't be trained to trust to begin with because it is unreliable" is a
good idea.

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Junio C Hamano @ 2009-10-17 17:43 UTC (permalink / raw)
  To: Julian Phillips
  Cc: Björn Steinbrink, Daniel Barkalow, James Pickens, Jeff King,
	Nicolas Pitre, Jay Soffian, git
In-Reply-To: <alpine.LNX.2.00.0910171617580.6644@reaper.quantumfyre.co.uk>

Julian Phillips <julian@quantumfyre.co.uk> writes:

>>> My interest in this thread is solely that it might provide a mechanism
>>> to find out which tag was checked out.
>>
>> Hmm, what is lacking in "git describe HEAD" for that?  I am not
>> complaining that you might be asking for something that exists, but I _do_
>> want to know if something that exists is not a satisfactory solution and
>> if so how it can be improved.
>
> What is lacking is the "checked out" part.  "git describe HEAD" will
> tell me _a_ tag that matches the currently checked out state.
> However, it makes no guarantee that it was the one I checked out.  If
> I tag the code with "v1.0.0", and a colleague later tags it with
> "this_version_sucks", then when I check out and build the code for the
> customer the version it reports could well be "this_version_sucks"
> instead of "v1.0.0" ...

I think I understand why you think showing what you gave to your last "git
checkout" (e.g. "checkout origin/master" or "checkout v1.0.0") and using
that as a build identification token is a good idea.  But "origin/master"
is a moving target---it depends on when you checked it out.  describe uses
tags and does not use branch heads for a good reason.

"v1.0.0" also is to a lessor degree, as you may have tagged v1.0.0 locally
and somebody else also has used the tag for a different version, but a tag
is far less likely to move due to social convention.  "describe --long"
would make sure this won't be an issue anyway, though.

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Björn Steinbrink @ 2009-10-17 17:48 UTC (permalink / raw)
  To: Julian Phillips
  Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
	Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <alpine.LNX.2.00.0910171829430.7906@reaper.quantumfyre.co.uk>

On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:
> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
> >Do you have multiple (annotated) tags for the same commit?
> 
> Potentially, yes.  Releasing isn't the only thing that requires
> keeping track of things.  It's even possible that the person
> creating the newer tag doesn't yet know that a release tag has been
> applied if the person who applied it hasn't yet pushed it back.

OK, I'd consider that namespace pollution, as things like
"this-version-sucks" doesn't seem like it show go into public repos, but
anyway. If your release tags fix into a certain "unique" format, you
could use describe with --match, like:
git describe --match 'v[0-9]*'

> >Otherwise, I don't see why "git describe HEAD" should print the
> >wrong one. If there's a tag that can be resolved to the same
> >commit that HEAD can be resolved, then "git describe HEAD" must
> >output that one. Otherwise, that'd be a clear bug to me.
> 
> Oh, definately no bug.  git describe works exactly as expected, the
> problem is that the tag checked out isn't always the latest tag
> applied to that commit.

I misworded that one. Should be "If there's only tag that can be ...".
IOW it was meant for "only one tag per commit", which is what I assumed
to be the case.

Björn

^ permalink raw reply

* [PATCH] Add the --submodule option to the diff option family
From: Jens Lehmann @ 2009-10-17 18:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Johannes Schindelin, Git Mailing List

When you use the option --submodule=left-right-log you can see the submodule
summaries inlined in the diff, instead of not-quite-helpful SHA-1 pairs.

The format imitates what "git submodule summary" shows.

To do that, <path>/.git/objects/ is added to the alternate object
databases (if that directory exists).

This option was requested by Jens Lehmann at the GitTogether in Berlin.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---


In this patch i tried to address all the issues mentioned so far, please
let me know if anything is missing.


 Documentation/diff-options.txt |    7 +++
 Makefile                       |    2 +
 diff.c                         |   16 ++++++
 diff.h                         |    1 +
 submodule.c                    |  112 ++++++++++++++++++++++++++++++++++++++++
 submodule.h                    |    8 +++
 6 files changed, 146 insertions(+), 0 deletions(-)
 create mode 100644 submodule.c
 create mode 100644 submodule.h

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 9276fae..99cb517 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -87,6 +87,13 @@ endif::git-format-patch[]
 	Show only names and status of changed files. See the description
 	of the `--diff-filter` option on what the status letters mean.

+--submodule[=<format>]::
+	Chose the output format for submodule differences. <format> can be one of
+	'short' and 'left-right-log'. 'short' is the default value for this
+	option and and shows pairs of commit names. 'left-right-log' lists the
+	commits in that commit range like the 'summary' option of
+	linkgit:git-submodule[1] does.
+
 --color::
 	Show colored diff.

diff --git a/Makefile b/Makefile
index c0eff64..2f61e17 100644
--- a/Makefile
+++ b/Makefile
@@ -453,6 +453,7 @@ LIB_H += sideband.h
 LIB_H += sigchain.h
 LIB_H += strbuf.h
 LIB_H += string-list.h
+LIB_H += submodule.h
 LIB_H += tag.h
 LIB_H += transport.h
 LIB_H += tree.h
@@ -551,6 +552,7 @@ LIB_OBJS += sideband.o
 LIB_OBJS += sigchain.o
 LIB_OBJS += strbuf.o
 LIB_OBJS += string-list.o
+LIB_OBJS += submodule.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += trace.o
diff --git a/diff.c b/diff.c
index c719ce2..8af1ae2 100644
--- a/diff.c
+++ b/diff.c
@@ -13,6 +13,7 @@
 #include "utf8.h"
 #include "userdiff.h"
 #include "sigchain.h"
+#include "submodule.h"

 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -1557,6 +1558,17 @@ static void builtin_diff(const char *name_a,
 	const char *a_prefix, *b_prefix;
 	const char *textconv_one = NULL, *textconv_two = NULL;

+	if (DIFF_OPT_TST(o, SUBMODULE_LEFT_RIGHT_LOG) &&
+			(!one->mode || S_ISGITLINK(one->mode)) &&
+			(!two->mode || S_ISGITLINK(two->mode))) {
+		const char *del = diff_get_color_opt(o, DIFF_FILE_OLD);
+		const char *add = diff_get_color_opt(o, DIFF_FILE_NEW);
+		show_submodule_summary(o->file, one ? one->path : two->path,
+				one->sha1, two->sha1,
+				del, add, reset);
+		return;
+	}
+
 	if (DIFF_OPT_TST(o, ALLOW_TEXTCONV)) {
 		textconv_one = get_textconv(one);
 		textconv_two = get_textconv(two);
@@ -2771,6 +2783,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
 		DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
 	else if (!strcmp(arg, "--ignore-submodules"))
 		DIFF_OPT_SET(options, IGNORE_SUBMODULES);
+	else if (!prefixcmp(arg, "--submodule=")) {
+		if (!strcmp(arg + 12, "left-right-log"))
+			DIFF_OPT_SET(options, SUBMODULE_LEFT_RIGHT_LOG);
+	}

 	/* misc options */
 	else if (!strcmp(arg, "-z"))
diff --git a/diff.h b/diff.h
index a7e7ccb..8079f5b 100644
--- a/diff.h
+++ b/diff.h
@@ -67,6 +67,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
 #define DIFF_OPT_DIRSTAT_BY_FILE     (1 << 20)
 #define DIFF_OPT_ALLOW_TEXTCONV      (1 << 21)
 #define DIFF_OPT_DIFF_FROM_CONTENTS  (1 << 22)
+#define DIFF_OPT_SUBMODULE_LEFT_RIGHT_LOG (1 << 23)
 #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
 #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
 #define DIFF_OPT_CLR(opts, flag)    ((opts)->flags &= ~DIFF_OPT_##flag)
diff --git a/submodule.c b/submodule.c
new file mode 100644
index 0000000..206386f
--- /dev/null
+++ b/submodule.c
@@ -0,0 +1,112 @@
+#include "cache.h"
+#include "submodule.h"
+#include "dir.h"
+#include "diff.h"
+#include "commit.h"
+#include "revision.h"
+
+int add_submodule_odb(const char *path)
+{
+	struct strbuf objects_directory = STRBUF_INIT;
+	struct alternate_object_database *alt_odb;
+
+	strbuf_addf(&objects_directory, "%s/.git/objects/", path);
+	if (!is_directory(objects_directory.buf))
+		return -1;
+
+	/* avoid adding it twice */
+	for (alt_odb = alt_odb_list; alt_odb; alt_odb = alt_odb->next)
+		if (alt_odb->name - alt_odb->base == objects_directory.len &&
+				!strncmp(alt_odb->base, objects_directory.buf,
+					objects_directory.len))
+			return 0;
+
+	alt_odb = xmalloc(objects_directory.len + 42 + sizeof(*alt_odb));
+	alt_odb->next = alt_odb_list;
+	strcpy(alt_odb->base, objects_directory.buf);
+	alt_odb->name = alt_odb->base + objects_directory.len;
+	alt_odb->name[2] = '/';
+	alt_odb->name[40] = '\0';
+	alt_odb->name[41] = '\0';
+	alt_odb_list = alt_odb;
+	prepare_alt_odb();
+	return 0;
+}
+
+void show_submodule_summary(FILE *f, const char *path,
+		unsigned char one[20], unsigned char two[20],
+		const char *del, const char *add, const char *reset)
+{
+	struct rev_info rev;
+	struct commit *commit, *left = left, *right;
+	struct commit_list *merge_bases, *list;
+	const char *message = NULL;
+	struct strbuf sb = STRBUF_INIT;
+	static const char *format = "  %m %s";
+	int fast_forward = 0, fast_backward = 0;
+
+	if (is_null_sha1(two))
+		message = "(submodule deleted)";
+	else if (add_submodule_odb(path))
+		message = "(not checked out)";
+	else if (is_null_sha1(one))
+		message = "(new submodule)";
+	else if (!(left = lookup_commit_reference(one)) ||
+		 !(right = lookup_commit_reference(two)))
+		message = "(commits not present)";
+
+	if (!message) {
+		init_revisions(&rev, NULL);
+		setup_revisions(0, NULL, &rev, NULL);
+		rev.left_right = 1;
+		rev.first_parent_only = 1;
+		left->object.flags |= SYMMETRIC_LEFT;
+		add_pending_object(&rev, &left->object, path);
+		add_pending_object(&rev, &right->object, path);
+		merge_bases = get_merge_bases(left, right, 1);
+		if (merge_bases) {
+			if (merge_bases->item == left)
+				fast_forward = 1;
+			else if (merge_bases->item == right)
+				fast_backward = 1;
+		}
+		for (list = merge_bases; list; list = list->next) {
+			list->item->object.flags |= UNINTERESTING;
+			add_pending_object(&rev, &list->item->object,
+				sha1_to_hex(list->item->object.sha1));
+		}
+		if (prepare_revision_walk(&rev))
+			message = "(revision walker failed)";
+	}
+
+	strbuf_addf(&sb, "Submodule %s %s..", path,
+			find_unique_abbrev(one, DEFAULT_ABBREV));
+	if (!fast_backward && !fast_forward)
+		strbuf_addch(&sb, '.');
+	strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
+	if (message)
+		strbuf_addf(&sb, " %s\n", message);
+	else
+		strbuf_addf(&sb, "%s:\n", fast_backward ? " (rewind)" : "");
+	fwrite(sb.buf, sb.len, 1, f);
+
+	if (!message) {
+		while ((commit = get_revision(&rev))) {
+			strbuf_setlen(&sb, 0);
+			if (commit->object.flags & SYMMETRIC_LEFT) {
+				if (del)
+					strbuf_addstr(&sb, del);
+			}
+			else if (add)
+				strbuf_addstr(&sb, add);
+			format_commit_message(commit, format, &sb,
+					rev.date_mode);
+			if (reset)
+				strbuf_addstr(&sb, reset);
+			strbuf_addch(&sb, '\n');
+			fprintf(f, "%s", sb.buf);
+		}
+		clear_commit_marks(left, ~0);
+		clear_commit_marks(right, ~0);
+	}
+}
diff --git a/submodule.h b/submodule.h
new file mode 100644
index 0000000..4c0269d
--- /dev/null
+++ b/submodule.h
@@ -0,0 +1,8 @@
+#ifndef SUBMODULE_H
+#define SUBMODULE_H
+
+void show_submodule_summary(FILE *f, const char *path,
+		unsigned char one[20], unsigned char two[20],
+		const char *del, const char *add, const char *reset);
+
+#endif
-- 
1.6.5.3.g464e1.dirty

^ permalink raw reply related

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Björn Steinbrink @ 2009-10-17 19:41 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Julian Phillips, Daniel Barkalow, James Pickens, Jeff King,
	Nicolas Pitre, Jay Soffian, git
In-Reply-To: <7vaazqcry5.fsf@alter.siamese.dyndns.org>

On 2009.10.17 02:04:02 -0700, Junio C Hamano wrote:
> The "save" part of the work-save-then-merge sequence should be made very
> visible to help people get used to the "not up, but work-save-then-merge"
> mental model.  I do not think it would help people in the long run to make
> the "save" step less visible by wrapping the sequence into an unreliable
> "up" script, especially because the script would sometimes work but other
> times *has to* force users to know that what is happening behind the scene
> is work-save-then-merge in order to resolve and recover from conflicts
> anyway.

Hm, which cases would that be? I basically see three cases:

 1) No uncommitted changes => No problem
 2) Uncommitted changes merge cleanly => No problem
 3) Uncommitted changes causes conflicts =>
   - User can resolve
   - User can start over (git update --retry)
   - User can give up (git update --abort)

Of course the user can clearly see that some state was saved (otherwise
you couldn't retry or abort), but I don't see how the user is "forced"
in any way, he just gets those two commands to work with (which
internally just wrap reset + stash apply, making things more
convenient).

I do see problems with a "stash around merge" thing ("stash" around
rebase seems easier, as that could just create a commit and reset later,
but I'm not exactly sure that such smartness is a good idea). As soon as
the merge has conflicts, you need to know that you have to unstash after
committing the merge, but what I have in mind is fast-forward only (or
possibly reset, when upstream was rewritten).  Primarily for users that
don't commit at all, but just look at things [*1*]. And also for the
semi-detached HEAD case, in which you may not commit and in which doing
a merge/rebase is therefore not an option, but git still knows what to
fetch/checkout by using the discussed extra info in HEAD, or by
examining the reflog.

> > OTOH, it might be easier to just tell the user to do the stash thing
> > himself. But I wonder how many users would really know how to get back
> > to the initial state then.
> 
> I agree with the first sentence, but I do not understand what "the initial
> state" you talk about here in the second sentence, sorry.

The state they were in before they did the "git stash" part.

*work on stuff not ready to be committed*
git pull # refused
git stash
git pull
git stash apply # Conflicts, user decides that he wants go back

At that point, you need the reflog (also handle fast-forwards), and do:

git reset --hard HEAD@{1}
git stash apply --index


Of course, a more correct way might be to use commit and rebase instead:

*work on stuff not ready to be committed*
git pull # refused
git add -A # Or whatever
git commit
git pull --rebase # conflicts, decide to abort
git rebase --abort
git reset HEAD^

But that still needs the extra "reset HEAD^" step to really get back to
the state with your uncommitted changes.

The problem with "svn up" is that there's no other way, and no way back.
Git has other ways, but no convenient one for non-committers and no
"obvious" way to go back, should you decide that you actually prefer not
to update after seeing the conflicts.

Anyway, this isn't _my_ itch and to some (large) degree I'm trying to
guess what someone else would expect. If at all, I'm more interested in
a command that figures out which remote tracking branch I checked out,
and that updates it, and updates my work tree/index as well. Uncommitted
changes aren't important to me there. So I'll simply give up on that
part.

Björn


[*1*] One could also say: Users that don't give a damn about git, but
just need it to get the code and maybe have some minor, uncommitted
modifications on top. I'm _not_ thinking about users that actually
commit and do stuff. Those should use merge/rebase/pull, and get a
complaint from "git update" if the update is not a fast-forward one,
telling them what to use instead.

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Daniel Barkalow @ 2009-10-17 20:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Christoph Bartoschek, git
In-Reply-To: <7vr5t2h3do.fsf@alter.siamese.dyndns.org>

On Sat, 17 Oct 2009, Junio C Hamano wrote:

> Christoph Bartoschek <bartoschek@gmx.de> writes:
> 
> [jc: added Daniel back to cc list; please do not cull the cc list without
> good reason]
> 
> > Daniel Barkalow wrote:
> >
> >> The upshot of the messages should be:
> >> 
> >>  $ git checkout origin/master
> >>  Since you can't actually change "origin/master" yourself, you'll just
> >>  be sightseeing unless you create a local branch to hold new local work.
> >> 
> >>  $ git branch
> >>  * (not a local branch, but "origin/master")
> >> 
> >>  $ git commit
> >>  You've been sightseeing "origin/master". The commit can't change that
> >>  value, so your commit isn't held in any branch. If you want to create
> >>  a branch to hold it, here's how.
> > ...
> > But then I was not able to verify that the checkout indeed matched the 
> > 1.3.0-beta.  "git status" and "git branch" did not help here. 
> 
> This is not going to help you, but "git reflog" would have helped here.
> 
> The reason my suggesting "git reflog" now won't help you is because the
> word "reflog" does not connect the question "how did I get here" unless
> and until you know git already; in other words, it is not your fault that
> you got lost, but it is showing a wart in the UI.
> 
> If the question you were asking was "does the files I have in my work tree
> after issuing that scary checkout actually match origin/1.3.0-beta?", you
> could have asked that question in a more direct way, and the command to do
> so is "git diff origin/1.3.0-beta".  I do not think this would be asking
> the user to be doing something unreasonably unintuitive.
> 
> If the question you were asking was (and it was not, from the description
> of your experience, but you could be in that situation when you "return
> some weeks later") "how does the checked out history relate to 1.3.0-beta?",
> then there is a way to ask the question in a very direct way, and the
> command to do so is "git show-branch HEAD origin/1.3.0-beta" (or give the
> same argument to "gitk").
> 
> Although it is not _so_ unreasonable to expect "git status" to show the
> information, I suspect it would not be practical.  After all, whenever
> somebody is lost, everything is "status".  For a person who is lost and
> does not know where in the history he is, it might be reasonable to expect
> "status" to give the relationship between your HEAD and some branch/tag,
> while for another person who was hit by "git gui" complaining that he has
> too many loose objects, it might be reasonable for him to expect "status"
> to give the number of loose objects in the repository.  IOW, "status" is
> too broad a word and following the path to cram everything into "status"
> so that any new person who gets lost can get necessary infor from the
> command will unfortunately lead to insanity.
> 
> The second item in the Daniel's transcript above may be an improvement but
> I think it is a wrong economy to record and show 'but "origin/master"'
> (which cannot be correct forever and has to be invalidated once the user
> starts committing or resetting) in the message.

It's easy to invalidate it for reasons of the user going elsewhere: you 
invalidate it when you invalidate MERGE_HEAD (which, incidentally, 
locates a bug in my original patch: there's a third 
"unlink(git_path("MERGE_HEAD"));" I didn't think of, in builtin-merge.c).

I think the case of it going stale, mainly due to updating a ref it uses, 
is a matter of having whatever wants to describe HEAD check if the 
extended sha1 still expands to the same sha1.

I also think that it fits with the git world model to distinguish 
"lvalues" from "non-lvalues". An "lvalue" is something where you can make 
a commit and change the value while the expression stays the same; you can 
assign to it. If your current position is not an "lvalue" and you commit, 
your current position must become a new temporary "lvalue", diverging from 
the thing you can't change. But if you don't assign to it, there's no 
problem with having a non-lvalue be your current position.

> I am wondering if a similar effect to help new users can be had by 
> rewording the message to:
> 
>     $ git branch
>     * (not a local branch; see "git reflog" to learn how you got here)
> 
> The user can see how he got there even after doing something else after
> the checkout (see Nico's write-up in $gmane/130527).  The difference is
> between giving fish and teaching how to catch one himself.

The reflog hint is a good one in general; on the other hand, I think it 
would be generally helpful to have the information in a more 
machine-readable fashion, for a "git checkout (whatever I gave to reset or 
checkout before)".

Perhaps the right implementation is actually to have machine-readable 
descriptions in the HEAD reflog? That would actually lead to the 
interesting:

$ git checkout topic
$ git checkout origin/master
$ git checkout HEAD@{1}
$ git branch
* topic

Actually, we turn out to have a flaw in our reflog explanation: when 
rebase finishes, it doesn't log that it's back to a particular branch.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [PATCH 0/3] Generalized "string function" syntax
From: René Scharfe @ 2009-10-17 21:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1255681702-5215-1-git-send-email-gitster@pobox.com>

Junio C Hamano schrieb:
> I mentioned an idea to enhance the pretty=format language with a
> string function syntax that people can extend by adding new functions
> in one of the "What's cooking" messages earlier.  The general syntax
> would be like
> 
> %[function(args...)any string here%]
> 
> where "any string here" part would have the usual pretty=format
> strings. E.g.  git show -s --format='%{w(72,8,4)%s%+b%]' should give
> you a line wrapped commit log message if w(width,in1,in2) is such a
> function.

I pondered line wrapping with format strings briefly a long time ago, and
I always considered it to be more similar to a colour, i.e. a state that
one can change and that is applied to all following text until the next
state change.  (Except that it's always reset at the end of the format
string.)  The example above would then turn into '%w(72,8,4)%s%+b'.

Here's a patch to implement this behaviour.  It leaves the implementation
of the actual wrap function as an exercise to the reader, too. ;-)


 pretty.c |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/pretty.c b/pretty.c
index f5983f8..33464f1 100644
--- a/pretty.c
+++ b/pretty.c
@@ -445,6 +445,7 @@ struct format_commit_context {
 	enum date_mode dmode;
 	unsigned commit_header_parsed:1;
 	unsigned commit_message_parsed:1;
+	size_t width, indent1, indent2;
 
 	/* These offsets are relative to the start of the commit message. */
 	struct chunk author;
@@ -458,6 +459,7 @@ struct format_commit_context {
 	struct chunk abbrev_commit_hash;
 	struct chunk abbrev_tree_hash;
 	struct chunk abbrev_parent_hashes;
+	size_t wrap_start;
 };
 
 static int add_again(struct strbuf *sb, struct chunk *chunk)
@@ -595,6 +597,44 @@ static void format_decoration(struct strbuf *sb, const struct commit *commit)
 		strbuf_addch(sb, ')');
 }
 
+static void strbuf_wrap(struct strbuf *sb, size_t pos, size_t len,
+			size_t width, size_t indent1, size_t indent2)
+{
+	struct strbuf tmp = STRBUF_INIT;
+
+	if (!len)
+		return;
+	if (pos)
+		strbuf_add(&tmp, sb->buf, pos);
+
+	/* XXX: all that's missing is the wrapping code itself.. */
+	strbuf_addf(&tmp, "w(%u,%u,%u)[\n",
+		    (unsigned)width, (unsigned)indent1, (unsigned)indent2);
+	strbuf_add(&tmp, sb->buf + pos, len);
+	strbuf_addstr(&tmp, "\n]");
+
+	if (pos + len < sb->len)
+		strbuf_add(&tmp, sb->buf + pos + len, sb->len - pos - len);
+	strbuf_swap(&tmp, sb);
+	strbuf_release(&tmp);
+}
+
+static void rewrap_message_tail(struct strbuf *sb,
+				struct format_commit_context *c,
+				size_t new_width, size_t new_indent1,
+				size_t new_indent2)
+{
+	if (c->width == new_width && c->indent1 == new_indent1 &&
+	    c->indent2 == new_indent2)
+		return;
+	strbuf_wrap(sb, c->wrap_start, sb->len - c->wrap_start, c->width,
+		    c->indent1, c->indent2);
+	c->wrap_start = sb->len;
+	c->width = new_width;
+	c->indent1 = new_indent1;
+	c->indent2 = new_indent2;
+}
+
 static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
                                void *context)
 {
@@ -645,6 +685,30 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
 			return 3;
 		} else
 			return 0;
+	case 'w':
+		if (placeholder[1] == '(') {
+			unsigned long width = 0, indent1 = 0, indent2 = 0;
+			char *next;
+			const char *start = placeholder + 2;
+			const char *end = strchr(start, ')');
+			if (!end)
+				return 0;
+			if (end > start) {
+				width = strtoul(start, &next, 10);
+				if (*next == ',') {
+					indent1 = strtoul(next + 1, &next, 10);
+					if (*next == ',') {
+						indent2 = strtoul(next + 1,
+								 &next, 10);
+					}
+				}
+				if (*next != ')')
+					return 0;
+			}
+			rewrap_message_tail(sb, c, width, indent1, indent2);
+			return end - placeholder + 1;
+		} else
+			return 0;
 	}
 
 	/* these depend on the commit */
@@ -748,7 +812,9 @@ void format_commit_message(const struct commit *commit,
 	memset(&context, 0, sizeof(context));
 	context.commit = commit;
 	context.dmode = dmode;
+	context.wrap_start = sb->len;
 	strbuf_expand(sb, format, format_commit_item, &context);
+	rewrap_message_tail(sb, &context, 0, 0, 0);
 }
 
 static void pp_header(enum cmit_fmt fmt,

^ permalink raw reply related

* Re: [PATCH 1/3] format_commit_message(): fix function signature
From: René Scharfe @ 2009-10-17 21:04 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <1255681702-5215-2-git-send-email-gitster@pobox.com>

Junio C Hamano schrieb:
> The format template string was declared as "const void *" for some unknown
> reason, even though it obviously is meant to be passed a string.  Make it
> "const char *".

Yes.  I seem to have introduced that type in commit 7b95089c, but I
can't see (even less remember) why.  Also note that commit message and
header file call the parameter "template", while it's called "format" in
commit.c (where the function used to live back then).  What was I thinking?

Thanks for cleaning up after me.

René

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 22:19 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Björn Steinbrink, Daniel Barkalow, James Pickens, Jeff King,
	Nicolas Pitre, Jay Soffian, git
In-Reply-To: <7vljj97w7u.fsf@alter.siamese.dyndns.org>

On Sat, 17 Oct 2009, Junio C Hamano wrote:

> Julian Phillips <julian@quantumfyre.co.uk> writes:
>
>>>> My interest in this thread is solely that it might provide a mechanism
>>>> to find out which tag was checked out.
>>>
>>> Hmm, what is lacking in "git describe HEAD" for that?  I am not
>>> complaining that you might be asking for something that exists, but I _do_
>>> want to know if something that exists is not a satisfactory solution and
>>> if so how it can be improved.
>>
>> What is lacking is the "checked out" part.  "git describe HEAD" will
>> tell me _a_ tag that matches the currently checked out state.
>> However, it makes no guarantee that it was the one I checked out.  If
>> I tag the code with "v1.0.0", and a colleague later tags it with
>> "this_version_sucks", then when I check out and build the code for the
>> customer the version it reports could well be "this_version_sucks"
>> instead of "v1.0.0" ...
>
> I think I understand why you think showing what you gave to your last "git
> checkout" (e.g. "checkout origin/master" or "checkout v1.0.0") and using
> that as a build identification token is a good idea.  But "origin/master"
> is a moving target---it depends on when you checked it out.  describe uses
> tags and does not use branch heads for a good reason.

For my purposes the branch that I built from is much more useful than the 
output from describe.  Releases are always made from tags, but for builds 
used in the lab it is generally much more useful to know which branch was 
built directly rather than being able to find the exact commit that was 
built.

> "v1.0.0" also is to a lessor degree, as you may have tagged v1.0.0 locally
> and somebody else also has used the tag for a different version, but a tag
> is far less likely to move due to social convention.  "describe --long"
> would make sure this won't be an issue anyway, though.

For any particular release only one person is given the job of making the 
release tag, so we don't have the problem of multiple instances of the 
same tag - but we do need to make sure that the version output is the 
correct tag.

-- 
Julian

  ---
Water, taken in moderation cannot hurt anybody.
 		-- Mark Twain

^ permalink raw reply

* Re: git submodules
From: Nanako Shiraishi @ 2009-10-17 22:30 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Git Mailing List, Steven Noonan, crawl-ref-discuss
In-Reply-To: <m3tyxydj8f.fsf@localhost.localdomain>

Quoting Jakub Narebski <jnareb@gmail.com>

> Steven Noonan <steven@uplinklabs.net> writes:
>
>> We're using git submodules for the contributing libraries. When I
>> commit changes to those contribs, it correctly shows in the parent
>> repository that those folders have different revisions than what's
>> currently committed. However, if someone pulls those changes, it
>> doesn't automatically update the contribs to match the committed
>> version. But doing a pull or merge _should_ update the working tree to
>> match the committed versions. It does with file data, so why not
>> update the submodules? Especially if the submodule revision matched
>> the committed version -before- the pull. Why are we forced into using
>> 'git submodule update'?
>
> Because you might want not to use most current version of submodule,
> so git-pull shouldn't update submodules by default.  And because
> git-pull didn't learn --recursive option yet.

I don't think your description is correct. Steven is talking about what the command should do by default. If you checked out the current superproject, by default you should get the submodule that matches. If you don't want the most current version, you can checkout an older submodule yourself.

You may want to follow this discussion:

  http://thread.gmane.org/gmane.comp.version-control.git/130155/focus=130330

After stating that he isn't against the idea to make it automatic, Junio describes what needs to be done for it to happen and what are the corner cases that needs to be treated with care.

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply

* Re: [PATCH] Proof-of-concept patch to remember what the detached HEAD was
From: Julian Phillips @ 2009-10-17 22:28 UTC (permalink / raw)
  To: Björn Steinbrink
  Cc: Nicolas Pitre, Junio C Hamano, Daniel Barkalow, James Pickens,
	Jeff King, Jay Soffian, Git Mailing List
In-Reply-To: <20091017174843.GA16251@atjola.homenet>

On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:

> On 2009.10.17 18:35:38 +0100, Julian Phillips wrote:
>> On Sat, 17 Oct 2009, Bj?rn Steinbrink wrote:
>>> Do you have multiple (annotated) tags for the same commit?
>>
>> Potentially, yes.  Releasing isn't the only thing that requires
>> keeping track of things.  It's even possible that the person
>> creating the newer tag doesn't yet know that a release tag has been
>> applied if the person who applied it hasn't yet pushed it back.
>
> OK, I'd consider that namespace pollution, as things like
> "this-version-sucks" doesn't seem like it show go into public repos, but
> anyway. If your release tags fix into a certain "unique" format, you
> could use describe with --match, like:
> git describe --match 'v[0-9]*'

Well - that only helps if we only ever build the release tags.  Which 
isn't the case.  The other tags are there for similar purposes and also 
should go into the version string - but only when they were the tag 
checked out.

Is it really that unreasonable to want to know exactly what it was that 
was checked out?  It's one of the few things that I miss from Subversion.

-- 
Julian

  ---
printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled :-)\n");
         linux-2.6.6/drivers/message/fusion/mptbase.c

^ permalink raw reply

* [ANNOUNCE] GIT 1.6.5.1
From: Junio C Hamano @ 2009-10-18  1:04 UTC (permalink / raw)
  To: git

The latest maintenance release GIT 1.6.5.1 is available at the
usual places:

  http://www.kernel.org/pub/software/scm/git/

  git-1.6.5.1.tar.{gz,bz2}			(source tarball)
  git-htmldocs-1.6.5.1.tar.{gz,bz2}		(preformatted docs)
  git-manpages-1.6.5.1.tar.{gz,bz2}		(preformatted docs)

The RPM binary packages for a few architectures are found in:

  RPMS/$arch/git-*-1.6.5.1-1.fc9.$arch.rpm	(RPM)

GIT v1.6.5.1 Release Notes
==========================

Fixes since v1.6.5
------------------

 * An corrupt pack could make codepath to read objects into an
   infinite loop.

 * Download throughput display was always shown in KiB/s but on fast links
   it is more appropriate to show it in MiB/s.

 * "git grep -f filename" used uninitialized variable and segfaulted.

 * "git clone -b branch" gave a wrong commit object name to post-checkout
   hook.

 * "git pull" over http did not work on msys.

Other minor documentation updates are included.

----------------------------------------------------------------

Changes since v1.6.5 are as follows:

Björn Steinbrink (1):
      clone: Supply the right commit hash to post-checkout when -b is used

Johannes Sixt (1):
      remote-curl: add missing initialization of argv0_path

Junio C Hamano (1):
      GIT 1.6.5.1

Matt Kraai (1):
      grep: do not segfault when -f is used

Miklos Vajna (1):
      git-stash documentation: mention default options for 'list'

Nicolas Pitre (1):
      change throughput display units with fast links

Shawn O. Pearce (1):
      sha1_file: Fix infinite loop when pack is corrupted

^ permalink raw reply

* How to revert one of multiple merges
From: Bill Lear @ 2009-10-18  2:31 UTC (permalink / raw)
  To: git

Branch A, B, C each have 20 commits, 0-19.

Branch v1.0.0 created, then merge of A, B, C performed.

After testing, we realize that the branch B is not ready for
production release and we'd like to remove it from branch
v1.0.0.

If I do

% git merge A B C

I get a single commit:

% git log -p

commit 1644a0b98c01869aa83e59aa41374c22098c47b6
[...]
Date:   Fri Oct 16 09:52:32 2009 -0500

    Merge branches 'A', 'B' and 'C' into v1.0.0

[20 x 3 commits]

If I do

% git merge A
% git merge B
% git merge C

Then:

% git log -p

commit 8946edd381384d0882221c87b5b3b7bf47127d70
[...]
Date:   Sat Oct 17 21:28:36 2009 -0500

    Merge branch 'B' into v1.0.0

commit 076ed422443e3684e564f7cae2b92e4538088ae6
[...]
Date:   Sat Oct 17 21:28:35 2009 -0500

    Merge branch 'A' into v1.0.0

but no "Merge branch 'C' into v1.0.0".

And so, I'm faced with git rebase -i posing some unanswerable questions
to our release manager.  She cannot easily remove B from the merge after
doint either merge A B C, or merge A, merge B, merge C.

Can anyone help?


Bill

^ permalink raw reply

* Re: [PATCH 0/3] Generalized "string function" syntax
From: Junio C Hamano @ 2009-10-18  4:18 UTC (permalink / raw)
  To: René Scharfe; +Cc: git
In-Reply-To: <4ADA3153.7070606@lsrfire.ath.cx>

René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:

> Junio C Hamano schrieb:
>> I mentioned an idea to enhance the pretty=format language with a
>> string function syntax that people can extend by adding new functions
>> in one of the "What's cooking" messages earlier.  The general syntax
>> would be like
>> 
>> %[function(args...)any string here%]
>> 
>> where "any string here" part would have the usual pretty=format
>> strings. E.g.  git show -s --format='%{w(72,8,4)%s%+b%]' should give
>> you a line wrapped commit log message if w(width,in1,in2) is such a
>> function.
>
> I pondered line wrapping with format strings briefly a long time ago, and
> I always considered it to be more similar to a colour, i.e. a state that
> one can change and that is applied to all following text until the next
> state change.  (Except that it's always reset at the end of the format
> string.)  The example above would then turn into '%w(72,8,4)%s%+b'.

As a syntax to express "wrapping" behaviour alone, I think this is much
simpler and more superiour.  I guess with this if you want to wrap
something to 72 columns and then wrap something else to 66 columns, you
would write '%w(72,8,4)something%w(66,8,4)something else', right?

I used %] only for two reasons.

 - Without an explicit "here it ends", I couldn't come up with a good way
   to express '%[w(72,8,4)something%]something else'.  IOW, how I can say
   "wrap something to 72 columns and then place something else without any
   wrapping"?
   
 - When we need to support more than one string function like this, it is
   unclear what '%f()one string%g()another one' in your syntax means.
   Does it mean '%[f()one string%]%[g()another one%]' (i.e. concatenate
   the result of applying string function f to 'one string' and the result
   of applying string function g to 'another one')?  Or does it mean
   '%[f()one string%[g()another one%]%]' (apply 'f' to concatenation of
   'one string' and the result of applying 'g' to 'another one')?

^ permalink raw reply

* Re: [PATCH v3.1 3/5] Introduce new pretty formats %g[sdD] for reflog information
From: Jeff King @ 2009-10-18  7:18 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Jef Driesen, Nanako Shiraishi, git
In-Reply-To: <e0ab6923eb4057bcbc8e97980dad5e4a37e53067.1255790816.git.trast@student.ethz.ch>

On Sat, Oct 17, 2009 at 04:48:11PM +0200, Thomas Rast wrote:

> > +NOTE: Some placeholders may depend on other options given to the
> > +revision traversal engine. For example, the `%g*` reflog options will
> > +insert an empty string unless we are traversing reflog entries (e.g., by
> > +`git log -g`). The `%d` placeholder will use the "short" decoration
> > +format if `--decorate` was not already provided on the command line.
> 
> Sure.  I figured it was obvious enough, but since you already went to
> the lengths of documenting the exact behaviour of %d, I squashed it
> and adjusted the acknowledgement in the commit message accordingly.

If the consensus (or Junio's decision when applying) is that we don't
need it, I don't mind if my suggestion is scrapped (or reworded).

-Peff

^ permalink raw reply

* Re: [PATCH/RFC] builtin-checkout: suggest creating local branch when appropriate to do so
From: Junio C Hamano @ 2009-10-18  7:58 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Jay Soffian, git
In-Reply-To: <alpine.DEB.1.00.0910052314580.4985@pacific.mpi-cbg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Actually, we should really think long and hard why we should not 
> automatically check out the local branch "next" in that case.

While people were thinking long and hard, I've spent some quality time
having fun with these patches, and realized that if we limit the scope of
the change to make sure that we only change the behaviour of a case where
we refused to do anything, this is not even something we need to think
long nor hard after all.

At least from the maintainer's point of view, that is.

I on the other hand do agree that we need to think long and hard when it
comes to the matter of explaining this to the users, though.  I couldn't
come up with a good (re-)ordering of the documentation to fit this new
"short-cut" into the manpage.

A three-patch series will follow shortly.

^ permalink raw reply

* [PATCH 1/3] check_filename(): make verify_filename() callable without dying
From: Junio C Hamano @ 2009-10-18  8:00 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Jay Soffian
In-Reply-To: <7vzl7pyvzl.fsf@alter.siamese.dyndns.org>

Make it possible to invole the logic of verify_filename() to make sure the
pathname arguments are unambiguous without actually dying.  The caller may
want to do something different.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 cache.h |    1 +
 setup.c |   38 ++++++++++++++++++++------------------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/cache.h b/cache.h
index 96840c7..71a731d 100644
--- a/cache.h
+++ b/cache.h
@@ -396,6 +396,7 @@ extern const char *setup_git_directory_gently(int *);
 extern const char *setup_git_directory(void);
 extern const char *prefix_path(const char *prefix, int len, const char *path);
 extern const char *prefix_filename(const char *prefix, int len, const char *path);
+extern int check_filename(const char *prefix, const char *name);
 extern void verify_filename(const char *prefix, const char *name);
 extern void verify_non_filename(const char *prefix, const char *name);
 
diff --git a/setup.c b/setup.c
index 029371e..f67250b 100644
--- a/setup.c
+++ b/setup.c
@@ -61,6 +61,19 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 	return path;
 }
 
+int check_filename(const char *prefix, const char *arg)
+{
+	const char *name;
+	struct stat st;
+
+	name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
+	if (!lstat(name, &st))
+		return 1; /* file exists */
+	if (errno == ENOENT || errno == ENOTDIR)
+		return 0; /* file does not exist */
+	die_errno("failed to stat '%s'", arg);
+}
+
 /*
  * Verify a filename that we got as an argument for a pathspec
  * entry. Note that a filename that begins with "-" never verifies
@@ -70,18 +83,12 @@ const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
  */
 void verify_filename(const char *prefix, const char *arg)
 {
-	const char *name;
-	struct stat st;
-
 	if (*arg == '-')
 		die("bad flag '%s' used after filename", arg);
-	name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
-	if (!lstat(name, &st))
+	if (check_filename(prefix, arg))
 		return;
-	if (errno == ENOENT)
-		die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
-		    "Use '--' to separate paths from revisions", arg);
-	die_errno("failed to stat '%s'", arg);
+	die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
+	    "Use '--' to separate paths from revisions", arg);
 }
 
 /*
@@ -91,19 +98,14 @@ void verify_filename(const char *prefix, const char *arg)
  */
 void verify_non_filename(const char *prefix, const char *arg)
 {
-	const char *name;
-	struct stat st;
-
 	if (!is_inside_work_tree() || is_inside_git_dir())
 		return;
 	if (*arg == '-')
 		return; /* flag */
-	name = prefix ? prefix_filename(prefix, strlen(prefix), arg) : arg;
-	if (!lstat(name, &st))
-		die("ambiguous argument '%s': both revision and filename\n"
-		    "Use '--' to separate filenames from revisions", arg);
-	if (errno != ENOENT && errno != ENOTDIR)
-		die_errno("failed to stat '%s'", arg);
+	if (!check_filename(prefix, arg))
+		return;
+	die("ambiguous argument '%s': both revision and filename\n"
+	    "Use '--' to separate filenames from revisions", arg);
 }
 
 const char **get_pathspec(const char *prefix, const char **pathspec)
-- 
1.6.5.1.95.g09fbd

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox