Git development
 help / color / mirror / Atom feed
* Re: [PATCH/RFC] Convenient support of remote branches in git-checkout
From: Josef Weidendorfer @ 2006-11-07 17:04 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Junio C Hamano, git
In-Reply-To: <20061107135609.GA32376@diana.vm.bytemark.co.uk>

On Tuesday 07 November 2006 14:56, you wrote:
> But what happens when an unexperienced user gets this conflict for the
> first time (having for the first time used two different remotes)?
> Your scheme forces her to learn two new things instead of one,
> creating the artificial barrier I mentioned above.

I give the user a warning that she has to specify a branch
name herself. This does not force her to rename all her branches
and go with the new naming <remote>/<remote branch>, but probably
makes her do

 repo developer1, branch next => next (magic behavior)
 repo developer2, branch next => next2 (manual specification)

and perhaps rename next to next1 afterwards.

At least I do not want to type long branch names; most of the
cloned repos I have do have only one remote. So I would rename
the branches names created with the complex magic scheme.

Of course, another way is to be more smart with branch name parsing.
Currently, a given name is searched in
	.git/
	.git/refs/
	.git/refs/tags/
	.git/refs/heads/
	.git/refs/remotes/
	.git/refs/remotes/*/HEAD

What about adding before remotes
	.git/refs/heads/<first-part-of-current-branchname>/
and at the end
	.git/refs/remotes/<first-part-of-current-branchname>/
Ie. when on branch "origin/next", a given name "master" is
parsed as "refs/heads/origin/master" when existing?
So the parsing rule is: "With current branch X and given name Y,
search for a branch as near as possible to X which has Y as
last name component".

This would match current UI, where you have simple branch names
like "master" or "next".
With above rule, you can use "master" to refer
to "refs/heads/origin/master" in the complex model,
and for a read-only remote head "refs/heads/remotes/origin/next",
it is enough to say
	git-checkout next
to get a new local branch "refs/heads/origin/next" created
to work on.

You keep the simple UI and still get the perfect overview with
eg. with "gitk --all" even in the case where you work on
10s of remote branches from multiple repository.


^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Jakub Narebski @ 2006-11-07 16:39 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.64.0611070729370.3667@g5.osdl.org>

Linus Torvalds wrote:

> So doing a merge doesn't really "centralize" anything. It just joins the 
> two development threads together in that particular line. If "master" 
> merges the work in "maint", master doesn't really get any more 
> centralized, it just gets the work that "maint" did since last time. And 
> if there was no other work done at all, then the two branches end up 100% 
> identical - there was no "merge" of the work.

By the way, merges happen in _two_ directions. 'Master' merges from 'next'
when 'next' is in sufficiently stable state; 'next' merges from 'master' to
get changes which were considered stable enough to be put into
'master' (and 'master' merges in from 'maint', too).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Linus Torvalds @ 2006-11-07 16:05 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Junio C Hamano, git
In-Reply-To: <45503553.3020605@gmail.com>



On Tue, 7 Nov 2006, Liu Yubao wrote:
>
> > If a fast-forward were to do a "merge commit", you'd never get into the
> > situation where two people merging each other would really ever get a stable
> > result. They'd just keep doing merge commits on top of each other.
>
> They can stop merging a fake commit with a real commit that point to same
> tree object, here they reach a stable result: we have same tree content.

That's flawed for two reasons:

 - identical trees is meaningless. You can have identical trees that had 
   different histories and just happened to end up in the same state, and 
   you'd still generate a merge commit (because what merges do is show the 
   history of the data, and the _history_ merges). 

   So you're really just introducing a special case, and not even one that 
   makes any sense. Either history matters, or it doesn't.

 - a distributed system fundamnetally means that nobody is "special". And 
   a merge is a _joining_ of two threads. Neither of which is special. 

   Let's say that we have

	A:	a -> b -> c -> d

	B:	a -> b -> c

   and B pulls. You think that it should result in

	B:	a -> b -> c  --->  e
		            \    /
		             > d

   and I say that that is crazy, because in a distributed system, A and B 
   are _equivalent_ and have the same branches, and tell me what would 
   have happened if _A_ had pulled from _B_ instead?

   That's right: if A had pulled from B, then obviously nothing at all 
   would happen, because A already had everything B had.

   So the only _logical_ thing to happen is that the end result doesn't 
   depend on who merged. And that means that if B merged from A, then the 
   end result _has_ to be the same as if A merged from B, namely_

	B:	a -> b -> c -> d

   and nothing else. Anything else is insane. It's not a distributed 
   system any more.



> > Git tracks history, not "your view of history". Trying to track "your view"
> > is fundamentally wrong, because "your wiew" automatically means that the
> > project history would not be distributed any more - it would be centralized
> > around what _you_ think happened. That is not a sensible thing to have in a
> > distributed system.
>
> It's not my view, it's branch scope view, I can see how a branch evolves
> relatively independently.

No you CAN NOT. You think that "A" is special. But because you think that 
A is special, you ignore that B had the exact same branch, so your "branch 
scope view" is inherently flawed - it's not "branch scope" at all, it's 
literally a "one person is special" view.

> In git, branch scope view is more or less neglected. After fast 
> forwarding merge, I can' tell where a branch come from -- I mean the 
> track of a branch.

Sure you can. In your reflog. It's only _you_ who care about _your_ 
history. Nobody else cares one whit about what your tree looks like.

> If Junio publishes his reflog, I don't see what conflict will happen between
> his local view (but now public, and naming it branch scope view seems more
> sensible) and git's global view.

Why would anybody ever care about Junio's reflog?

Also, you're ignoring the issue that both I and Martin mentioned: you're 
making history harder to read, and adding crud that doesn't actually _do_ 
anything. Your approach is nonsensical from a distributed system 
standpoint, but it's also _worse_ than just fast-forwarding. If git did 
what you suggested, we'd have a lot of extra merge commits that simply 
don't _help_ anything, and only make things worse.

> What's the mean of upstream branch then? I have to know I should track
> Junio's public repository.

"Upstream" really should have absolutely zero meaning. That's the whole 
point of distributed. You can merge things sideways, down, up, and the end 
result doesn't matter. "upstream" can merge from you, and you can merge 
from him. Thats' the _technology_.

The only thing that matters is "trust". But trust is not something you get 
from technology, and trust is something you have to earn. And trust does 
NOT come from digital signatures like some people believe: digital 
signatures are a way of _verifying_ the trust you have, but they are very 
much secondary (or tertiary) to the real issues.

And _trust_ is why you'd pull from Junio. Git makes it somewhat easier by 
giving you default shorthands for the original place you cloned from when 
you clone a new repository, because often you'd obviously keep trusting 
the same source, but an important thing here is to realize that it really 
is "often". Not always. And it's not about technology.

> When does one say two branches reach a common point? have same commit(must
> point to same tree) or have same tree(maybe a fake commit and a real commit)?
> I think git takes the first way.

Very much so. To git, the only (and I really mean _only_) thing that 
matters from a commit history view is the commit relationships. NOTHING 
else. What the trees are doesn't matter at all. Where the commits came 
from doesn't matter. Who made them doesn't matter either - those are just 
"documentation".

So the _only_ thing that matters for a commit is what its place in history 
was. We never even look at the trees at all to decide what to do about 
merging. The only time the trees start to matter is when we've figured out 
what the merge relationship is, and then obviously the trees matter, but 
even then they only matter as far as the resulting _tree_ is concerned. 

> Fast forwarding style merge tends to *automatically* centralize many
> branches

Yes. Except I wouldn't say "centralize", I would very much say "join". 
That's the point of a merge. Two commit histories "join" and become one.

But the reason I don't agree with your choice of wording ("centralize")
thing is fundamental:

 - it only happens on one side. The side that does the merge is not 
   necessarily the "central" one at all.

 - there isn't necessarily even such a thing as a "central" branch in git 
   (and there _shouldn't_ be).

In fact, the thing I absolutely _detest_ about CVS is how it makes it 
almost impossible to have multiple "equally worthy" branches. Look at the 
git repository itself that Junio maintains, and please tell me which is 
the "trunk" branch?

Git doesn't even have that concept. There is the concept of a _default_ 
branch ("master"), and yes, the git repository has it. But at the same 
time, it really is just a default. There are three "main" branches that 
Junio maintains, and they only really differ in the degree of development. 
And "master" isn't even the most stable one - it's just the default one, 
because it's smack dab in the middle: recent enough to be interesting, but 
still stable enough to be worth tracking for just about anybody.

But really, "maint" is the stable branch, and in many ways you could say 
that "maint" is the trunk branch, since that's what Junio still cuts 
releases from. And "next" is the development branch, that gets interesting 
features before they hit the "master" branch (and "pu" is so far out that 
it's a whole different issue, since it jumps around and doesn't even 
become a real history at all).

See? All of these are _equal_. There is no trunk. There is no "central" 
branch, and if you were to have to decide which one is the most central 
one, it's not even the default one, that would probably be "maint", since 
that's the one that keeps getting merged into the other branches.

So doing a merge doesn't really "centralize" anything. It just joins the 
two development threads together in that particular line. If "master" 
merges the work in "maint", master doesn't really get any more 
centralized, it just gets the work that "maint" did since last time. And 
if there was no other work done at all, then the two branches end up 100% 
identical - there was no "merge" of the work.

They still have their own identities, though. It's still two branches. 
It's still "maint" and "master". They just have the exact same state, and 
that is as it should be, since they've had the exact same development 
history.


^ permalink raw reply

* [PATCH] git-pack-objects progress flag documentation and cleanup
From: Nicolas Pitre @ 2006-11-07 15:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This adds documentation for --progress and --all-progress, remove a 
duplicate --progress handling and make usage string more readable.

Signed-off-by: Nicolas Pitre <nico@cam.org>

---

diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 5ebe34e..fdc6f97 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -99,6 +99,23 @@ base-name::
         Only create a packed archive if it would contain at
         least one object.
 
+--progress::
+	Progress status is reported on the standard error stream
+	by default when it is attached to a terminal, unless -q
+	is specified. This flag forces progress status even if
+	the standard error stream is not directed to a terminal.
+
+--all-progress::
+	When --stdout is specified then progress report is
+	displayed during the object count and deltification phases
+	but inhibited during the write-out phase. The reason is
+	that in some cases the output stream is directly linked
+	to another command which may wish to display progress
+	status of its own as it processes incoming pack data.
+	This flag is like --progress except that it forces progress
+	report for the write-out phase as well even if --stdout is
+	used.
+
 -q::
 	This flag makes the command not to report its progress
 	on the standard error stream.
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 270bcbd..69e5dd3 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -15,7 +15,12 @@
 #include <sys/time.h>
 #include <signal.h>
 
-static const char pack_usage[] = "git-pack-objects [-q] [--no-reuse-delta] [--delta-base-offset] [--non-empty] [--local] [--incremental] [--window=N] [--depth=N] [--all-progress] [--revs [--unpacked | --all]*] [--stdout | base-name] <ref-list | <object-list]";
+static const char pack_usage[] = "\
+git-pack-objects [{ -q | --progress | --all-progress }] \n\
+	[--local] [--incremental] [--window=N] [--depth=N] \n\
+	[--no-reuse-delta] [--delta-base-offset] [--non-empty] \n\
+	[--revs [--unpacked | --all]*] [--stdout | base-name] \n\
+	[<ref-list | <object-list]";
 
 struct object_entry {
 	unsigned char sha1[20];
@@ -1520,14 +1525,6 @@ int cmd_pack_objects(int argc, const cha
 			local = 1;
 			continue;
 		}
-		if (!strcmp("--progress", arg)) {
-			progress = 1;
-			continue;
-		}
-		if (!strcmp("--all-progress", arg)) {
-			progress = 2;
-			continue;
-		}
 		if (!strcmp("--incremental", arg)) {
 			incremental = 1;
 			continue;
@@ -1550,6 +1547,10 @@ int cmd_pack_objects(int argc, const cha
 			progress = 1;
 			continue;
 		}
+		if (!strcmp("--all-progress", arg)) {
+			progress = 2;
+			continue;
+		}
 		if (!strcmp("-q", arg)) {
 			progress = 0;

^ permalink raw reply related

* Re: win2k/cygwin cannot handle even moderately sized packs
From: Jakub Narebski @ 2006-11-07 15:50 UTC (permalink / raw)
  To: git
In-Reply-To: <81b0412b0611070555u1833cc8ci1d37d45782562df8@mail.gmail.com>

Alex Riesen wrote:

>> So the problem is probably memory fragmentation.
> 
> probably.
> 
>> You might have more joy if you allocated one HUGE chunk immediately on
>> startup to use for the pack, and then kept re-using that chunk.
> 
> Well, it is not _one_ chunk. The windows/cygwin abomin...combination
> may take an issue with this: it seem to copy complete address space
> at fork, which even for such a small packs I have here takes system
> down lightly (yes, I tried it).

Perhaps planned mmapping only parts of packs would help there.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: [PATCH/RFC] Convenient support of remote branches in git-checkout
From: Karl Hasselström @ 2006-11-07 13:56 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Junio C Hamano, git
In-Reply-To: <200611071153.32840.Josef.Weidendorfer@gmx.de>

On 2006-11-07 11:53:32 +0100, Josef Weidendorfer wrote:

> On Tuesday 07 November 2006 07:54, you wrote:
>
> > Having more than one local branch for a remote branch is advanced
> > enough that the user should know how to create branches with any
> > name they choose.
>
> But such an advanced szenario is exactly the reason to introduce
> these long branch names like "origin/next", isn't it? When a newbie
> probably never is confronted with this szenario, then why give him
> longer branch names per default? Do you see the contradiction in
> this argument?

Well, I see your point. However, forcing users to have to unlearn and
relearn when they want to use more of git's power feels wrong. It
would present an artificial barrier for users wishing to proceed from
the newbie stage.

It's more important to have simple rules than to make these rules
generate short names. Long names are not conceptually difficult, just
a bit cumbersome at times.

> IMHO it should be the other way around: when an advanced user gets
> this conflict, he knows how to rename the branches by using this
> more elaborated scheme.

But what happens when an unexperienced user gets this conflict for the
first time (having for the first time used two different remotes)?
Your scheme forces her to learn two new things instead of one,
creating the artificial barrier I mentioned above.

-- 
Karl Hasselström, kha@treskal.com

^ permalink raw reply

* Re: win2k/cygwin cannot handle even moderately sized packs
From: Alex Riesen @ 2006-11-07 13:55 UTC (permalink / raw)
  To: Noel Grandin; +Cc: git
In-Reply-To: <45507965.3010806@peralex.com>

> So the problem is probably memory fragmentation.

probably.

> You might have more joy if you allocated one HUGE chunk immediately on
> startup to use for the pack, and then kept re-using that chunk.

Well, it is not _one_ chunk. The windows/cygwin abomin...combination
may take an issue with this: it seem to copy complete address space
at fork, which even for such a small packs I have here takes system
down lightly (yes, I tried it).


^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Andy Whitcroft @ 2006-11-07 13:15 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <4550772B.1040308@gmail.com>

Liu Yubao wrote:
> Andy Whitcroft wrote:
>>
>> One thing to remember, when you merge the destination into which you
>> merge will be HEAD^1, so by just following that you can get junio's view
>> of his branch as he made it.
>>
>> This is doesn't terminate properly, sucks the performance of your
>> machine and generally should be erased rather than run; but you get the
>> idea:
>>
>> let n=0
>> while git-show --pretty=one -s "next~$n"
>> do
>>         let "n=$n+1"
>> done | less
>>
>> -apw
>>
> This is not a right way to view a branch track in git, see Junio's
> explanation
> about this from http://marc.theaimsgroup.com/?l=git&m=116279354214757&w=2

Well in fact that message tells us more why a branch centric view is
likely not useful.  This output is still the majority of the time the
view from the branch integrators point of view.  If that is something
you care about, I am not sure it is something I care about.


^ permalink raw reply

* Re: [PATCH/RFC] Convenient support of remote branches in git-checkout
From: Josef Weidendorfer @ 2006-11-07 10:53 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: Junio C Hamano, git
In-Reply-To: <20061107065400.GA25737@diana.vm.bytemark.co.uk>

On Tuesday 07 November 2006 07:54, you wrote:
> > IMHO this kind of aliasing is awkward. When you want to start
> > another topic branch on the remote branch, or want to reference the
> > remote branch for diffs, you have to explicitly specify
> > "remotes/origin/next", making for more typing.
> 
> Having more than one local branch for a remote branch is advanced
> enough that the user should know how to create branches with any name
> they choose.

But such an advanced szenario is exactly the reason to introduce
these long branch names like "origin/next", isn't it?
When a newbie probably never is confronted with this szenario, then
why give him longer branch names per default?
Do you see the contradiction in this argument?

IMHO it should be the other way around: when an advanced user
gets this conflict, he knows how to rename the branches by using
this more elaborated scheme.

I understand that these long branch names implicity give you information
about the upstream (by including the remote shortcut in front),
but this information (like all branch attributes) should also be
easy available with "git branch --info" or similar. Especially,
when we introduce shortcuts like "@up" (i.e. git-show-ref @up).
 
> But I do agree that calling it "origin/next" the first time you
> branch, and "remotes/origin/next" subsequent times, is nonintuitive.
> However, this could be solved by the following message being printed
> the first time:
> 
>   $ git checkout origin/next
>   No local branch "origin/next" exists. Creating new local branch
>   "origin/next" off of remote branch "remotes/origin/next".

My patch already does something like this.


^ permalink raw reply

* Re: win2k/cygwin cannot handle even moderately sized packs
From: Noel Grandin @ 2006-11-07 12:17 UTC (permalink / raw)
  To: Alex Riesen; +Cc: git
In-Reply-To: <81b0412b0611070302h50541cd5mf0758afe0d6befda@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1632 bytes --]

Looking at
http://msdn2.microsoft.com/en-us/library/ms810627.aspx
it looks like
(a) windows provides 2G of address space to play with
(b) VirtualAlloc is constrained to allocating contiguous ranges of
memory within that 2G address space

So the problem is probably memory fragmentation.

You might have more joy if you allocated one HUGE chunk immediately on
startup to use for the pack,
and then kept re-using that chunk.


Alex Riesen wrote:
> For me, it fails even on 332Mb pack:
>
> $ git reset --hard 61bb7fcb
> fatal: packfile .git/objects/pack/pack-ad37...pack cannot be mapped.
>
> Instrumenting the code reveals that it fails on 348876870 bytes.
> Strangely enough, a cygwin program which just reads that pack
> many times without freeing the mem goes up to 1395507480 (1330Mb).
>
> If I replace the malloc (cygwin) with native VirtualAlloc(MEM_COMMIT)
> it reports that "Not enough storage is available to process this
> command",
> which is just ENOMEM, I think.
>
> This is a 2Gb machine, with almost 1.3Gb free, so I'm a bit confused,
> what could here go wrong (besides what already is wrong).
>
> Any ideas?
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


NOTICE: This email, and the contents thereof, 
are subject to the standard Peralex email disclaimer, which may 
be found at: http://www.peralex.com/disclaimer.html

If you cannot access the disclaimer through the URL attached 
 and you wish to receive a copy thereof please send 
 an email to email@peralex.com

^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Jakub Narebski @ 2006-11-07 12:17 UTC (permalink / raw)
  To: git
In-Reply-To: <45507692.7050100@gmail.com>

Liu Yubao wrote:
[...]
I think everything stems from the fact that git repositories which pull/push
with each other _share_ [parts of] DAG. Learn to live with it, or chose
different SCM. 

You want branch a path through DAG, not only as lineage sub-DAG... but
recodring this information is I think costly.

Note also that the pointers to DAG branches are can be name differently in
different repositories (e.g. 'master' in one repository might be 'origin'
in the other, and 'remotes/origin/master' in yet another).
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Liu Yubao @ 2006-11-07 12:08 UTC (permalink / raw)
  To: Andy Whitcroft; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <455055DD.2090903@shadowen.org>

Andy Whitcroft wrote:
> 
> One thing to remember, when you merge the destination into which you
> merge will be HEAD^1, so by just following that you can get junio's view
> of his branch as he made it.
> 
> This is doesn't terminate properly, sucks the performance of your
> machine and generally should be erased rather than run; but you get the
> idea:
> 
> let n=0
> while git-show --pretty=one -s "next~$n"
> do
>         let "n=$n+1"
> done | less
> 
> -apw
> 
This is not a right way to view a branch track in git, see Junio's explanation

^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Liu Yubao @ 2006-11-07 12:05 UTC (permalink / raw)
  To: Andy Whitcroft; +Cc: Andreas Ericsson, Junio C Hamano, git
In-Reply-To: <4550522D.9060503@shadowen.org>

Andy Whitcroft wrote:
> Liu Yubao wrote: 
> But in that situation you and Alice now have different actual history
> DAG's in your repositories.
> 
> Alice sees:
> a---b---c---d-----------h
>              \         /
>               e---f---g
> 
> Bob sees:
> a---b---c---d-----------h
>              \         / \
>               e---f---g---i
> 
> 
> If bob now adds a new commit 'j' and alice pulls it back we either have
> to then accept 'i' at alice's end or forever lose the identicality of
> the commit DAG.  At which point our primary benefit of the SHA1 ==
> parent == same commit for everyone is gone.  We can no longer say "this
> commit is broken" and everyone know which commit that is.
> 
Alice and bob have their own branch scope view respectively, they have two
different branches, their DAGs in *branch scope view* can
be different because they trace the history from different points.

In branch scope view, you see only one HEAD, it merges changes from
other branches. Each branch has its own commit DAG.

In global scope view, you see many HEADs, they fork and merge frequently,
here is only one big commit DAG, but you can never see the whole as branches
can be distributed over the world.

Fake commit doesn't break the DAG in global scope view, it has parents
as normal commit although the trees pointed by fake commit and its parent
are same. In fact, git has suck commit already:

   a (tree_1) -------  b (tree_2)  ---- d (tree_2) ---> master
    \                                    /
     `---------------  c (tree_2) ------' -----> test

If you don't pull from other, you can get different global DAG, it's normal 
obviously. It doesn't matter you get different DAG in branch scope, of course
they are different.

The problem is you can't get branch *track* from global scope view in git, you
can't tell which commits a branch has *referred to*. Note following HEAD^1 
isn't right as Junio pointed out 
(http://marc.theaimsgroup.com/?l=git&m=116279354214757&w=2).

Branch track is useful as people have requested reflog feature (realized, but
only for local purpose) and "note" extension in commit object.

If you have a commit A that I haven't pulled, I can't know what you
refer to when you say "Commit A introduced a bug". I must know where
to get this commit. After I pull it from other branch, We can say "this
commit is broken" and everyone know which commit that is.

>> We create a fake commit for fast forwarding style merge, this fake commit
>> is used to record the track of a branch, so we can always follow HEAD^1
>> to travel through the history of a branch. In fact, git pays more attention
>> to the history of *data modification* than history of *operation*, that is
>> right the subtle difference between content tracker and VCS, latter's
>> branch has more information(useful information, I think).
> 
> Any VCS is concerned with data modification and how its tracked.  There
> are two ways you can record history.  A series of snapshots (git) or a
> series of operations (eg cvs and svn).  Each has its trade offs,
> operations like diff on snapshots is O(number of files), on diffs they
> are O(number of files * number of deltas).
> 
> The difference here is all about the interpretation of the word
> 'branch'.  In CVS and others there is the hard concept of a mainline --
> here is the master copy when something is added here it is "the one",
> branches are temporary places which contain 'different' history such as
> a patch branch.  You want something on both branches you commit the
> change twice once to each.  In git they are more separate future
> histories.  When they are merged back together the new single history
> contains the changes in both, neither is more important than the other
> both represent forward progress.  People tend to draw as below giving a
> false importance to the 'line' from d->h:
> 
> a---b---c---d-----------h
>              \         /
>               e---f---g
> 
> We probabally should draw the below, h's history contains all history
> from both 'up' and 'down' histories.  Which is more important?  Neither.
>  h is made up of a,b,c,d from alice and e,f,g from bob merged by alice.
> 
>               ---------
>              /         \
> a---b---c---d           h
>              \         /
>               e---f---g
> 
> 
If fake commit is introduced, a possible revision graph is like this:

   a - * -- c  ------- * ---> branchA
    \ /      \         /
     b ------ * ---- d ---> branchB      ('*' stands for fake commit)

It's indeed not pretty as a linear revision graph that git's fast forwarding
style merge creates, but it can record the tracks of two branches by following
HEAD^1.

^ permalink raw reply

* Re: [PATCH/RFC] Convenient support of remote branches in git-checkout
From: Josef Weidendorfer @ 2006-11-07 10:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7iy89ffs.fsf@assigned-by-dhcp.cox.net>

On Tuesday 07 November 2006 03:08, you wrote:
> I do not think we want a _new_ command.  It may make sense to
> enrich 'git-branch' for that.

I agree.

Probably similar, git-clone should use git-checkout at the end.

> If "git-checkout -b" does not use 'git-branch' to create a new
> branch in the current code, maybe we should, regardless of the
> usability enhancements under discussion.

Yes.

Josef

PS: This is one of the moments I wished git-branch still was a shell

^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Eran Tromer @ 2006-11-07 11:46 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0611060928180.3667@g5.osdl.org>

Hi Linus,

On 2006-11-06 19:48, Linus Torvalds wrote:
> 
> On Mon, 6 Nov 2006, Linus Torvalds wrote:
>> Besides, doing an empty commit like that ("I fast forwarded") literally 
>> doesn't add any true history information. It literally views history not 
>> as history of the _project_, but as the history of just one of the 
>> repositories. And that's wrong.
> 
> Btw, absolutely the _only_ reason people seem to want to do this is 
> because they want to "pee in the snow" and put their mark on things. They 
> seem to want to show "_I_ did this", even if the "doing" was a total 
> no-op and they didn't actually generate any real value.

In a project that uses topic branches extensively, the merge-induced
commits give a useful cue about the logical grouping of patches. They
let you easily glean the coarse-grained history and independent lines of
work ("pickaxe made it to next", "Linus got the libata updates") without
getting bogged down by individual commits, just by looking at the gitk
graph. Fast-forwards lose this information, and the more you encourage
them, the less grokkable history becomes.

Empty commits may be the wrong tool to address this (for all the reasons
you gave), but there's certainly useful process information that's
currently being lost.


^ permalink raw reply

* win2k/cygwin cannot handle even moderately sized packs
From: Alex Riesen @ 2006-11-07 11:02 UTC (permalink / raw)
  To: git

For me, it fails even on 332Mb pack:

$ git reset --hard 61bb7fcb
fatal: packfile .git/objects/pack/pack-ad37...pack cannot be mapped.

Instrumenting the code reveals that it fails on 348876870 bytes.
Strangely enough, a cygwin program which just reads that pack
many times without freeing the mem goes up to 1395507480 (1330Mb).

If I replace the malloc (cygwin) with native VirtualAlloc(MEM_COMMIT)
it reports that "Not enough storage is available to process this command",
which is just ENOMEM, I think.

This is a 2Gb machine, with almost 1.3Gb free, so I'm a bit confused,
what could here go wrong (besides what already is wrong).


^ permalink raw reply

* [PATCH] remove an unneeded test
From: Tero Roponen @ 2006-11-07 10:44 UTC (permalink / raw)
  To: git


In wt-status.c there is a test which does nothing.
This patch removes it.

Signed-off-by: Tero Roponen <teanropo@jyu.fi>

diff --git a/wt-status.c b/wt-status.c
index 9692dfa..7943944 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -102,8 +102,6 @@ static void wt_status_print_updated_cb(s
 	struct wt_status *s = data;
 	int shown_header = 0;
 	int i;
-	if (q->nr) {
-	}
 	for (i = 0; i < q->nr; i++) {
 		if (q->queue[i]->status == 'U')

^ permalink raw reply related

* Re: [PATCH/RFC] Convenient support of remote branches in git-checkout
From: Josef Weidendorfer @ 2006-11-07 10:28 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vvels6lf4.fsf@assigned-by-dhcp.cox.net>

On Tuesday 07 November 2006 03:27, Junio C Hamano wrote:
> remotes/origin/next as "next's upstream".  While we are on
> 'next' branch, we might want to refer to "HEAD's upstream".
> 
> I am not sure what the syntax for that should be, though.
> Perhaps "HEAD@upstream"?

I remember an idea floating around was to use a virtual
branch "ORIGIN" which always maps to the upstream of the current
branch.
 
> Unlike the regular extended sha1 expression modifiers such as
> name~n, name^n, and name^{type}, it does not work with arbitrary
> object name; it can only work with a refname.  Which is similar
> to the '@{time}' notation we added when we started using
> ref-log.  Strictly speaking these should not belong to the sha1
> naming layer, but we can have them anyway for the user's
> convenience.

Yes, this makes sense. Branch relations like "upstream" is a
local configuration issue, similar to reflogs.

I vote for "HEAD@up", short form "@up".


^ permalink raw reply

* Re: [PATCH] Add a MIME-Version header to e-mails
From: Catalin Marinas @ 2006-11-07  9:53 UTC (permalink / raw)
  To: Karl Hasselström; +Cc: git
In-Reply-To: <20061106074532.10376.60478.stgit@localhost>

Karl,

On 06/11/06, Karl Hasselström <kha@treskal.com> wrote:
> This is required by some mail servers that want to change the transfer
> encoding of the mail.

Thanks for digging into this problem and thanks to everyone else
(especially Linus) for the detailed explanations.

I'll include these patches (maybe modified) and I'll try to fix
"import" as well.

-- 

^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Andy Whitcroft @ 2006-11-07  9:46 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <45503553.3020605@gmail.com>

Liu Yubao wrote:
> Linus Torvalds wrote:
>>
>> On Mon, 6 Nov 2006, Liu Yubao wrote:
>>> Then, what bad *logical* problem will happen if a merging that is
>>> really a
>>> fast forwarding creates a new commit?
>>
>> You MUST NOT do that.
>>
>> If a fast-forward were to do a "merge commit", you'd never get into
>> the situation where two people merging each other would really ever
>> get a stable result. They'd just keep doing merge commits on top of
>> each other.
> They can stop merging a fake commit with a real commit that point to same
> tree object, here they reach a stable result: we have same tree content.
>>
>> Git tracks history, not "your view of history". Trying to track "your
>> view" is fundamentally wrong, because "your wiew" automatically means
>> that the project history would not be distributed any more - it would
>> be centralized around what _you_ think happened. That is not a
>> sensible thing to have in a distributed system.
> It's not my view, it's branch scope view, I can see how a branch evolves
> relatively independently. In git, branch scope view is more or less
> neglected.
> After fast forwarding merge, I can' tell where a branch come from -- I mean
> the track of a branch.
> 
> If Junio publishes his reflog, I don't see what conflict will happen
> between
> his local view (but now public, and naming it branch scope view seems more
> sensible) and git's global view.
> 
> If this won't lead to problems, it seems also ok to use fake commit for
> fast forwarding style merge, so we can follow HEAD^1 to travel through a
> branch without reflog.
> 
> I hope I have expressed my thought clearly.
>>
>> For example, the way to break the "infinite merges" problem above is
>> to say that _you_ would be special, and you would do a "fast-forward
>> commit", and the other side would always just fast-forward without a
>> commit. But that is very fundamentally against the whole point of
>> being distributed. Now you're special.
> No one is special as everybody can create fake commit, any branch (almost
> a tag) will never be overwritten to point to a commit object in
> another branch, branches are relatively independent, that's to say
> 'git log' will reflect what has happened really in current branch (a CVS
> semantical branch, not only a tag that always points to a tip commit).
>>
>> In fact, even for "you", it would be horrible - because you personally
>> might have 5 different repositories on five different machines. You'd
>> have to select _which_ machine you want to track. That's simply
>> insane. It's a totally broken model. (You can even get the same
>> situation with just _one_ repository, by just having five different
>> branches - you have to decide which one is the "main" branch).
> What's the mean of upstream branch then? I have to know I should track
> Junio's public repository.
> 
> When does one say two branches reach a common point? have same commit(must
> point to same tree) or have same tree(maybe a fake commit and a real
> commit)?
> I think git takes the first way.
> 
> Fast forwarding style merge tends to *automatically* centralize many
> branches,  in CVS people merge two branches and drop side branch to
> centralize them, they all have central semantics.
> (I don't want to get flame war between CVS/SVN and GIT, I think
> git is better than them really:-)
>>
>> Besides, doing an empty commit like that ("I fast forwarded")
>> literally doesn't add any true history information. It literally views
>> history not as history of the _project_, but as the history of just
>> one of the repositories. And that's wrong.
> Something like 'git log --follow-all-parent' can show history of the
> project
> as 'git log' does now.
>>
>> So just get used to it. You MUST NOT do what you want to do. It's stupid.
> Yes, I have understood the git way and am getting used to it, I like
> its simple but powerful design and great efficiency, thank all for your
> good work!
>>
>> If you want to track the history of one particular local branch, use
>> the "reflog" thing. It allows you to see what one of your local
>> branches contained at any particular time.
>>
>> See
>>
>>     [core]
>>         logAllRefUpdates = true
>>
> Thanks, it's a pity I can't pull Junio's reflog :-(

One thing to remember, when you merge the destination into which you
merge will be HEAD^1, so by just following that you can get junio's view
of his branch as he made it.

This is doesn't terminate properly, sucks the performance of your
machine and generally should be erased rather than run; but you get the
idea:

let n=0
while git-show --pretty=one -s "next~$n"
do
        let "n=$n+1"
done | less


^ permalink raw reply

* Re: If merging that is really fast forwarding creates new commit [Was: Re: how to show log for only one branch]
From: Andy Whitcroft @ 2006-11-07  9:30 UTC (permalink / raw)
  To: Liu Yubao; +Cc: Andreas Ericsson, Junio C Hamano, git
In-Reply-To: <454FFCE6.70408@gmail.com>

Liu Yubao wrote:
> Andreas Ericsson wrote:
>> Liu Yubao wrote:
>>
>> If "fake" commits (i.e., commits that doesn't change any content) are
>> introduced for each merge, it will change the ancestry graph and the
>> resulting tree(s) won't be mergable with the tree it merged with,
>> because each such "back-merge" would result in
>> * the "fake" commit becoming part of history
>> * a new "fake" commit being introduced
>>
>> Consider what happens when Alice pulls in Bob's changes. The
>> merge-base of Bob's tip is where Alice HEAD points to, so it results
>> in a fast-forward, like below.
>>
>> a---b---c---d               <--- Alice
>>              \
>>               e---f---g     <--- Bob
>>
>>
>> If, we would have created a fake commit instead, Alice would get a
>> graph that looks like so:
>>
>> a---b---c---d-----------h   <--- Alice
>>              \         /
>>               e---f---g     <--- Bob
>>
>>
>> Now, we would have two trees that are identical, because the merge
>> can't cause conflicts, but Alice and Bob will have reached it in two
>> different ways. When Bob decides he wants to go get the changes Alice
>> has done, his tree will look something like this:
>>
>> a---b---c---d-----------h          <--- Alice
>>              \         / \
>>               e---f---g---i        <--- Bob
>>
>>
>> He finds it odd that he's got two commits that, when checked out, lead
>> to the exact same tree, so he asks Alice to get his tree and see
>> what's going on. Alice will then end up with this:
>>
>> a---b---c---d-----------h---j      <--- Alice
>>              \         / \ /
>>               e---f---g---i        <--- Bob
>>
>>
>> Now there's four commits that all point to identical trees, but the
>> ancestry graphs differ between all developers. In the case above,
>> there's only two people working at the same project. Imagine the
>> amount of empty commits you'd get in a larger project, like the Linux
>> kernel.
>>
> Oh, you remind me, but I have a naive solution for this problem: print
> a hint and don't merge commits that contain fake commit, then I know I have
> reached a stable merge point and have same tree with others.

But in that situation you and Alice now have different actual history
DAG's in your repositories.

Alice sees:
a---b---c---d-----------h
             \         /
              e---f---g

Bob sees:
a---b---c---d-----------h
             \         / \
              e---f---g---i


If bob now adds a new commit 'j' and alice pulls it back we either have
to then accept 'i' at alice's end or forever lose the identicality of
the commit DAG.  At which point our primary benefit of the SHA1 ==
parent == same commit for everyone is gone.  We can no longer say "this
commit is broken" and everyone know which commit that is.

> 
> We create a fake commit for fast forwarding style merge, this fake commit
> is used to record the track of a branch, so we can always follow HEAD^1
> to travel through the history of a branch. In fact, git pays more attention
> to the history of *data modification* than history of *operation*, that is
> right the subtle difference between content tracker and VCS, latter's
> branch has more information(useful information, I think).

Any VCS is concerned with data modification and how its tracked.  There
are two ways you can record history.  A series of snapshots (git) or a
series of operations (eg cvs and svn).  Each has its trade offs,
operations like diff on snapshots is O(number of files), on diffs they
are O(number of files * number of deltas).

The difference here is all about the interpretation of the word
'branch'.  In CVS and others there is the hard concept of a mainline --
here is the master copy when something is added here it is "the one",
branches are temporary places which contain 'different' history such as
a patch branch.  You want something on both branches you commit the
change twice once to each.  In git they are more separate future
histories.  When they are merged back together the new single history
contains the changes in both, neither is more important than the other
both represent forward progress.  People tend to draw as below giving a
false importance to the 'line' from d->h:

a---b---c---d-----------h
             \         /
              e---f---g

We probabally should draw the below, h's history contains all history
from both 'up' and 'down' histories.  Which is more important?  Neither.
 h is made up of a,b,c,d from alice and e,f,g from bob merged by alice.

              ---------
             /         \
a---b---c---d           h
             \         /
              e---f---g


> 
> Even if no fake commit is created as git does now, there can be multiple
> commits with identical tree object, and git can't prevent you from merging
> two commits with identical tree object, it just creates an ancestry
> relation
> to remember the merge point.
> 
> As git(7) says:
>         The "commit" object is an object that introduces the notion
>         of history into the picture. In contrast to the other objects,
>         it doesn't just describe the physical state of a tree, it
>         describes how we got there, and why.
> 
> So it's clearer to describe a revision graph with nodes for tree
> objects and edges for commit objects(multiple edges for a merge
> commit object, I know this will break your habit:-).

How would such a graph look any different?

>> Fast-forward is a Good Thing and the only sensible thing to do in a
>> system designed to be fully distributed (i.e., where there isn't
>> necessarily any middle point with which everybody syncs), while
>> scaling beyond ten developers that merge frequently between each other.
>>
>>> If we throw away all compatibility, efficiency, memory and disk
>>> consumption
>>> problems,
>>> (1) we can get the track of a branch without reflog because HEAD^1 is
>>> always the tip of target branch(or working branch usually) before
>>> merging.
>>>
>>> (2) with the track, branch mechanism in git is possibly easier to
>>> understand,
>>> especially for newbies from CVS or Subversion, I really like git's
>>> light weight, simple but powerful design and great efficiency, but I
>>> am really
>>> surprised that 'git log' shows logs from other branches and a side
>>> branch can become part of main line suddenly.
>>>
>>> A revision graph represents fast forwarding style merging like this:
>>>
>>>             (fast forwarding)
>>>  ---- a ............ * ------> master
>>>        \            /
>>>         b----------c -----> test         (three commits with three
>>> trees)
>>>
>>> can be changed to:
>>>
>>>  ---- a (tree_1) ----------- d (tree_3) ------> master
>>>        \                    /
>>>         b (tree_2) ------- c (tree_3) ----> test
>>> (four commits with three trees, it's normal as more than one way can
>>> reach Rome :-)
>>>
>>
>> That's where our views differ. In my eyes, "d" and "c" are exactly
>> identical, and I'd be very surprised if the scm tried to tell me that
>> they aren't, by not giving them the same revid.

These two arn't identicle.  You have two difference routes to Rome, you
have two different lines on your map.  To just say 'they' are the same
and throw one away is to throw away just that history you care about.

> It doesn't matter, they have same tree, and it's normal too in git
> multiple commits have same tree, if you use nodes for tree state,
> that graph will be simple to understand:
> 
>           a              d
>         -----tree_1 -------------- tree_3 ----> master
>                  \                    / \
>                   \ b               d/c  `-----> test
>                    \                /
>                     `--- tree_2 ---'
> 
> This is the familiar way we used in CVS, I believe there are more
> than one people confused by fast forwarding style merge and 'git log'
> in git.


^ permalink raw reply

* [PATCH] syncing disk in a subprocess with a 60 seconds timeout.
From: Christian Thaeter @ 2006-11-07  9:07 UTC (permalink / raw)


sync() can take excessive long time, up to hours in some circumstances.
(eg. running badblocks on slow disk, dd'ing disk images, packet-writing on optical media)
Running a prune is usually expected to start (and complete) soon, especially
if it is initiated from a cron-script.

This patch forks the sync() in a background process and waits at most 60 seconds for
it's completion. If the sync doesnt complete in time or any other error occurs, prunning
is aborted and can be tried again a later time. Note that the sync() process will get
orphaned and sit around until syncing eventually completes.
---
 builtin-prune-packed.c |   35 +++++++++++++++++++++++++++++++++--
 1 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/builtin-prune-packed.c b/builtin-prune-packed.c
index 24e3b0a..05ac696 100644
--- a/builtin-prune-packed.c
+++ b/builtin-prune-packed.c
@@ -1,5 +1,7 @@
 #include "builtin.h"
 #include "cache.h"
+#include <time.h>
+#include <sys/wait.h>
 
 static const char prune_packed_usage[] =
 "git-prune-packed [-n]";
@@ -53,11 +55,16 @@ void prune_packed_objects(int dryrun)
 	}
 }
 
+void sig_nop(int unused){(void)unused;};
+
 int cmd_prune_packed(int argc, const char **argv, const char *prefix)
 {
 	int i;
 	int dryrun = 0;
-
+	pid_t syncpid;
+	struct timespec synctimeout;
+	int sleeping;
+		
 	for (i = 1; i < argc; i++) {
 		const char *arg = argv[i];
 
@@ -71,7 +78,31 @@ int cmd_prune_packed(int argc, const cha
 		/* Handle arguments here .. */
 		usage(prune_packed_usage);
 	}
-	sync();
+	
+	synctimeout.tv_sec = 60;
+	synctimeout.tv_nsec = 0;
+		
+	signal(SIGCLD, sig_nop);
+	syncpid = fork();
+	if (syncpid == 0) {
+		sync();
+		return 0;
+	}
+	else if (syncpid > 0) {
+		do {
+			if (waitpid(syncpid, NULL, WNOHANG) > 0)
+				break;
+			sleeping = nanosleep(&synctimeout, &synctimeout);
+			if (sleeping == -1) {
+				if (errno != EINTR)
+					die ("nanosleep error");
+			}
+			else
+				die ("coudn't sync within 60 seconds, nothing pruned");
+		} while (1);
+	}
+	else die("failed to fork sync process");
+	signal(SIGCLD, SIG_DFL);
 	prune_packed_objects(dryrun);
 	return 0;
 }
-- 
1.4.3.2

^ permalink raw reply related

* Re: [RFC] git-gui: A commit / fetch / push interface
From: Jakub Narebski @ 2006-11-07  8:58 UTC (permalink / raw)
  To: git
In-Reply-To: <20061107083603.GB9622@spearce.org>

Shawn Pearce wrote:

> Paul Mackerras originally started a thread about gitool, a graphical
> interface for creating commits:
> 
>   http://thread.gmane.org/gmane.comp.version-control.git/26415
[...]
> I have posted a repository with the source on pasky's service:
> 
>       http://repo.or.cz/w/git-gui.git
[...]
> Suggestions for improvement (or patches!) are most welcome.
> Better naming suggestions are also welcome.  :)

I have added it to http://git.or.cz/gitwiki/InterfacesFrontendsAndTools
By the way, do you know if (h)gct is actively developed against git?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply

* [RFC] git-gui: A commit / fetch / push interface
From: Shawn Pearce @ 2006-11-07  8:36 UTC (permalink / raw)
  To: git; +Cc: paulus

Paul Mackerras originally started a thread about gitool, a graphical
interface for creating commits:

  http://thread.gmane.org/gmane.comp.version-control.git/26415

I liked it and wanted to start making it available to some folks I
work with who are more comfortable with the mouse than they are with
the keyboard.  At first I tried fixing a few of the outstanding bugs
in gitool but I eventually wound up rewriting the thing from scratch.

The git-gui interface looks pretty similar to the gitool interface
(thanks Paul for laying out a such good idea!).  In the top 1/3
of the window there are two panes listing the modified files; the
middle 1/3 shows the diff against HEAD; the bottom 1/3 is used to
edit the commit message.

Clicking on a file icon in the top 1/3 area will update the index
via an update-index call, thereby scheduling the file for commit.
Right now however you can't undo the update (on the TODO list).  :-)

Clicking on a file name will show the diff against HEAD, or a 3 way
diff against HEAD, index and working directory, or just the file's
contents (depending on state of the file).


Major improvements over Paul's original gitool are:

 * Amend the last commit.

 * Merge commits (no merge resolution assitance however).

 * Automatic loading of MERGE_MSG and SQUASH_MSG buffers.

 * Fetch and push available from with the GUI.

 * Start gitk on the current branch.

 * Some useful keyboard bindings (though probably could use more).

 * Proper menus and menubar.

 * Provides status feedback to the user.

 * Prevents the user from doing parallel operations that might
   also affect the current operation (well at least from within
   git-gui anyway).

 * Default geometry works properly on Windows.

 * Stays running if invoked as git-gui; exits immediately after
   commit if invoked as git-citool.

 * Tested on Cygwin/Windows 2000 and Mac OS X.

 * Never crashes with Tcl/Tk errors.

Ok so that last one might be reaching. :-) While trying to improve
gitool I noticed that gitool kept throwing Tcl/Tk errors at various
times.  I had a hard time tracking down most of them.  (This is
one of the reasons I just rewrote it.)  I have yet to break git-gui.

I have posted a repository with the source on pasky's service:

	http://repo.or.cz/w/git-gui.git


My goal is to have enough operations available through git-gui that
the average user won't need to leave it, unless he/she needs to do a
cherry-pick, am, etc. type of operation.  Or they want to browse the
history, in which case they can just start gitk from within git-gui.
I'm hoping to have most of it done this week.  :-)

Suggestions for improvement (or patches!) are most welcome.
Better naming suggestions are also welcome.  :)

-- 

^ permalink raw reply

* Re: how to show log for only one branch
From: Jakub Narebski @ 2006-11-07  8:21 UTC (permalink / raw)
  To: git
In-Reply-To: <454FEDA5.1050607@gmail.com>

Liu Yubao wrote:

> Junio C Hamano wrote:
>> [...]  It is also a bad
>> example because I can answer that question with this command
>> line:
>> 
>>      git log --grep='^Merge .* into next$' next
>> 
>> and while it is a perfectly valid answer, I know it would leave
>> you feeling somewhat cheated.
>> 
> smart trick, but if the logs aren't consistent enough it's hard to
> grep them out.

Well, commit message for merges are generated automatically. And if you set
merge.summary=true in repo config (or your config), then you have shortlog
in merge commit message by default...
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git


^ permalink raw reply


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