Git development
 help / color / mirror / Atom feed
* [PATCH v2 3/4] commit.c: use clear_commit_marks_many() in in_merge_bases_many()
From: Junio C Hamano @ 2013-03-05 22:47 UTC (permalink / raw)
  To: git
In-Reply-To: <1362523639-30566-1-git-send-email-gitster@pobox.com>

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 commit.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/commit.c b/commit.c
index d12e799..b4512ab 100644
--- a/commit.c
+++ b/commit.c
@@ -876,8 +876,7 @@ int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit *
 	if (commit->object.flags & PARENT2)
 		ret = 1;
 	clear_commit_marks(commit, all_flags);
-	for (i = 0; i < nr_reference; i++)
-		clear_commit_marks(reference[i], all_flags);
+	clear_commit_marks_many(nr_reference, reference, all_flags);
 	free_commit_list(bases);
 	return ret;
 }
-- 
1.8.2-rc2-194-g549a9ef

^ permalink raw reply related

* [PATCH v2 2/4] commit.c: add in_merge_bases_many()
From: Junio C Hamano @ 2013-03-05 22:47 UTC (permalink / raw)
  To: git
In-Reply-To: <1362523639-30566-1-git-send-email-gitster@pobox.com>

Similar to in_merge_bases(commit, other) that returns true when
commit is an ancestor (i.e. in the merge bases between the two) of
the other commit, in_merge_bases_many(commit, n_other, other[])
checks if commit is an ancestor of any of the other[] commits.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 commit.c | 24 ++++++++++++++++++------
 commit.h |  1 +
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/commit.c b/commit.c
index 4757e50..d12e799 100644
--- a/commit.c
+++ b/commit.c
@@ -859,25 +859,37 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit)
 }
 
 /*
- * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
+ * Is "commit" an ancestor of one of the "references"?
  */
-int in_merge_bases(struct commit *commit, struct commit *reference)
+int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference)
 {
 	struct commit_list *bases;
-	int ret = 0;
+	int ret = 0, i;
 
-	if (parse_commit(commit) || parse_commit(reference))
+	if (parse_commit(commit))
 		return ret;
+	for (i = 0; i < nr_reference; i++)
+		if (parse_commit(reference[i]))
+			return ret;
 
-	bases = paint_down_to_common(commit, 1, &reference);
+	bases = paint_down_to_common(commit, nr_reference, reference);
 	if (commit->object.flags & PARENT2)
 		ret = 1;
 	clear_commit_marks(commit, all_flags);
-	clear_commit_marks(reference, all_flags);
+	for (i = 0; i < nr_reference; i++)
+		clear_commit_marks(reference[i], all_flags);
 	free_commit_list(bases);
 	return ret;
 }
 
+/*
+ * Is "commit" an ancestor of (i.e. reachable from) the "reference"?
+ */
+int in_merge_bases(struct commit *commit, struct commit *reference)
+{
+	return in_merge_bases_many(commit, 1, &reference);
+}
+
 struct commit_list *reduce_heads(struct commit_list *heads)
 {
 	struct commit_list *p;
diff --git a/commit.h b/commit.h
index b997eea..5057f14 100644
--- a/commit.h
+++ b/commit.h
@@ -171,6 +171,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads,
 
 int is_descendant_of(struct commit *, struct commit_list *);
 int in_merge_bases(struct commit *, struct commit *);
+int in_merge_bases_many(struct commit *, int, struct commit **);
 
 extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
 extern int run_add_interactive(const char *revision, const char *patch_mode,
-- 
1.8.2-rc2-194-g549a9ef

^ permalink raw reply related

* [PATCH v2 1/4] commit.c: add clear_commit_marks_many()
From: Junio C Hamano @ 2013-03-05 22:47 UTC (permalink / raw)
  To: git
In-Reply-To: <1362523639-30566-1-git-send-email-gitster@pobox.com>

clear_commit_marks(struct commit *, unsigned) only can clear flag
bits starting from a single commit; introduce an API to allow
feeding an array of commits, so that flag bits can be cleared from
commits reachable from any of them with a single traversal.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 commit.c | 19 +++++++++++++------
 commit.h |  1 +
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/commit.c b/commit.c
index e8eb0ae..4757e50 100644
--- a/commit.c
+++ b/commit.c
@@ -463,14 +463,23 @@ static void clear_commit_marks_1(struct commit_list **plist,
 	}
 }
 
-void clear_commit_marks(struct commit *commit, unsigned int mark)
+void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark)
 {
 	struct commit_list *list = NULL;
-	commit_list_insert(commit, &list);
+
+	while (nr--) {
+		commit_list_insert(*commit, &list);
+		commit++;
+	}
 	while (list)
 		clear_commit_marks_1(&list, pop_commit(&list), mark);
 }
 
+void clear_commit_marks(struct commit *commit, unsigned int mark)
+{
+	clear_commit_marks_many(1, &commit, mark);
+}
+
 void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark)
 {
 	struct object *object;
@@ -797,8 +806,7 @@ struct commit_list *get_merge_bases_many(struct commit *one,
 	if (!result || !result->next) {
 		if (cleanup) {
 			clear_commit_marks(one, all_flags);
-			for (i = 0; i < n; i++)
-				clear_commit_marks(twos[i], all_flags);
+			clear_commit_marks_many(n, twos, all_flags);
 		}
 		return result;
 	}
@@ -816,8 +824,7 @@ struct commit_list *get_merge_bases_many(struct commit *one,
 	free_commit_list(result);
 
 	clear_commit_marks(one, all_flags);
-	for (i = 0; i < n; i++)
-		clear_commit_marks(twos[i], all_flags);
+	clear_commit_marks_many(n, twos, all_flags);
 
 	cnt = remove_redundant(rslt, cnt);
 	result = NULL;
diff --git a/commit.h b/commit.h
index b6ad8f3..b997eea 100644
--- a/commit.h
+++ b/commit.h
@@ -134,6 +134,7 @@ struct commit *pop_most_recent_commit(struct commit_list **list,
 struct commit *pop_commit(struct commit_list **stack);
 
 void clear_commit_marks(struct commit *commit, unsigned int mark);
+void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark);
 void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark);
 
 /*
-- 
1.8.2-rc2-194-g549a9ef

^ permalink raw reply related

* [PATCH v2 0/4] push --follow-tags
From: Junio C Hamano @ 2013-03-05 22:47 UTC (permalink / raw)
  To: git

The primary change since the last round is that it pushes out only
annotated tags that are missing from the other side.

Junio C Hamano (4):
  commit.c: add clear_commit_marks_many()
  commit.c: add in_merge_bases_many()
  commit.c: use clear_commit_marks_many() in in_merge_bases_many()
  push: --follow-tags

 Documentation/git-push.txt |  8 +++-
 builtin/push.c             |  2 +
 commit.c                   | 42 ++++++++++++++------
 commit.h                   |  2 +
 remote.c                   | 99 ++++++++++++++++++++++++++++++++++++++++++++++
 remote.h                   |  3 +-
 t/t5516-fetch-push.sh      | 73 ++++++++++++++++++++++++++++++++++
 transport.c                |  2 +
 transport.h                |  1 +
 9 files changed, 218 insertions(+), 14 deletions(-)

-- 
1.8.2-rc2-194-g549a9ef

^ permalink raw reply

* Re: auto merge bug
From: David Krmpotic @ 2013-03-05 22:13 UTC (permalink / raw)
  To: Junio C Hamano, git
In-Reply-To: <194F685F-9460-42C6-B5A5-59475F53D038@gmail.com>

Hi guys! Thank you for responses.. I haven't suspected that repos
created via GitHub windows app would have union set by default :( have
to ask them about it.. it seems wrong to me… Here are the defaults for
a windows repo created with GitHub for windows app:

logo (master)$ cat .gitattributes
# Auto detect text files and perform LF normalization
* text=auto

# Custom for Visual Studio
*.cs     diff=csharp
*.sln    merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union

# Standard to msysgit
*.doc	 diff=astextplain
*.DOC	 diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot  diff=astextplain
*.DOT  diff=astextplain
*.pdf  diff=astextplain
*.PDF	 diff=astextplain
*.rtf	 diff=astextplain
*.RTF	 diff=astextplain

While investigating my problem I have read about the special union
merge mode, but didn't check if maybe my repo was in that mode..
really didn't expect it.

THANK YOU again… now I'll write to the github guys..


David

^ permalink raw reply

* Re: Load testing of git
From: Yuri Mikhailov @ 2013-03-05 22:04 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: thomas, git
In-Reply-To: <CAJo=hJvX5rmsuB4Jsbp7ZoqeyPtB_fwiZc=8VMWmF=HN0XKGLw@mail.gmail.com>

Thanks to everyone. The information was useful.

On 24 February 2013 21:31, Shawn Pearce <spearce@spearce.org> wrote:
> On Sun, Feb 24, 2013 at 8:58 AM, Thomas Koch <thomas@koch.ro> wrote:
>> Yuri Mikhailov:
>>> Dear Git community,
>>>
>>> I am a Software Developer and I have been using git for a while.
>>> Currently my company is looking for a version control system to use
>>> and we find Git a good candidate for us. But what is important for us
>>> to know is scalability of this VCS. Does anyone performed load testing
>>> of Git? What is the practical maximum number of files and revisions
>>> this system can handle?
>>>
>>> Best regards,
>>> Iurii Mykhailov
>>
>> Have a look at the projects using Git[1]. There are for sure projects that
>> exceeds the scalability you're thinking about. The linux Kernel might be the
>> biggest project.
>
> I highly doubt the Linux kernel is the biggest project.
>
> IIRC WebKit has more objects, more files, etc. Its repository's
> compressed form is >4G.
>
> I know of at least some proprietary repositories with 96G in them. Not
> much history, but a lot of binary blobs around 128M each doesn't
> compress well. And bup wasn't used so we didn't get very good
> compression over the files.

^ permalink raw reply

* Re: rebase destroys branches
From: Philip Oakley @ 2013-03-05 22:04 UTC (permalink / raw)
  To: Gene Thomas [DATACOM], Git List
In-Reply-To: <C057AC9B02D06A49810E9597C11F55BF14DFE5214F@dnzwgex2.datacom.co.nz>

From: "Gene Thomas [DATACOM]" <Gene.Thomas@datacom.co.nz>
Sent: Tuesday, March 05, 2013 1:05 AM
> Philip,
>        Thanks for your reply.
>
>>The original branch is not 'destroyed', rather the pointer to the
>>previous tip is within the logs.
>
> Is that the 'git log' log or internal logs? Are you sure? There
> doesn't appear to be a way to checkout that tip of see the log back
> from that tip.

Double checking the [rebase] manual page... [The ref] "ORIG_HEAD is set
to point at the tip of the branch before the reset."

So your original branch starts there (I just checked one of mine).
Obviously this is only for the machine that did the rebase, and only has
the last rebase tip. But then until it's pushed to an open repo no one 
knows ;-)

>
>>All the content is still available until the logs expire.
>
> So we will be unable to checkout content after a time?
>
> Gene Thomas.
>
> -----Original Message-----
> From: Philip Oakley [mailto:philipoakley@iee.org]
> Sent: Tuesday, 5 March 2013 12:44
> To: Gene Thomas [DATACOM]; Git List
> Subject: Re: rebase destroys branches
>
> From: "Gene Thomas [DATACOM]" <Gene.Thomas@datacom.co.nz>
> Sent: Monday, March 04, 2013 11:06 PM
>>Hello,
>>I am evaluating git for use in a company. Please correct if I am
>>wrong.
>>I am concerned that an inexperienced developer could mistakenly rebase
>>branches, destroying the original branch.
>
> The original branch is not 'destroyed', rather the pointer to the
> previous tip is within the logs. All the content is still available
> until the logs expire.
>
>>   Attached is a script (Windoze)
>>that shows the 'topic' branch being moved!, after the rebase we are
>>unable to see the original branch, read it's history or find it's
>>commit points.
>
>>Surely no operation should remove anything from the repository.
>>Operations like this irreversibly break the repository . When rebasing
>>the original branch must be retained.
>
> It's easy to misread some of Git's strengths if you have come from
> other historic corporate 'version control systems' which are often
> based on drawing office practice of old (e.g. the belief there is a
> single master to be protected is one misconception for software).
>
> Rebase, at the personal level, is an important mechanism for staff to
> prepare better code and commit messages. Trying to hide the reality
> will just make your management 'control' less effective as staff work
> around it and delay check-ins, etc.
>
> The broader access control and repo management issues are deliberately
> not part of Git, and there are good tools for that. e.g. Gitolite.
>
>>Yours faithfully,
>
>
>>Gene Thomas.
>
> Philip
>

^ permalink raw reply

* [PATCH] reflog: fix typo in "reflog expire" clean-up codepath
From: Junio C Hamano @ 2013-03-05 21:39 UTC (permalink / raw)
  To: git

In "reflog expire" we were not clearing the REACHABLE bit from
objects reachable from the tip of refs we marked earlier.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/reflog.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/reflog.c b/builtin/reflog.c
index b3c9e27..ef56e7b 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -414,7 +414,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
 		if (cb.unreachable_expire_kind == UE_HEAD) {
 			struct commit_list *elem;
 			for (elem = tips; elem; elem = elem->next)
-				clear_commit_marks(tip_commit, REACHABLE);
+				clear_commit_marks(elem->item, REACHABLE);
 			free_commit_list(tips);
 		} else {
 			clear_commit_marks(tip_commit, REACHABLE);
-- 
1.8.2-rc2-187-g1ea4a7c

^ permalink raw reply related

* Re: "git rebase" loses the additional changes in "evil" merges
From: Junio C Hamano @ 2013-03-05 21:35 UTC (permalink / raw)
  To: Dale Worley; +Cc: git
In-Reply-To: <201303052118.r25LIoAC000463@freeze.ariadne.com>

Dale Worley <worley@c-66-31-108-177.hsd1.ma.comcast.net> writes:

>> From: Junio C Hamano <gitster@pobox.com>
>> 
>> I think this is to be expected for "git rebase", as it does not even
>> look at merges.  It is a way to find non-merge commits that haven't
>> been applied yet, and apply them to the upstream to create a new
>> linear history.
>
> I disagree. "git rebase" is not characterized as ...

The intention has always been "I have these patches, some were
applied upstream already, now what do I have left?".

You do realize that you are disagreeing with somebody who designed
the original "git rebase" (before the --preserve-merges was added),
do you?

^ permalink raw reply

* Re: Git hook commit similar to subversion start-commit hook
From: John Keeping @ 2013-03-05 21:31 UTC (permalink / raw)
  To: Jose Garcia Juanino; +Cc: git
In-Reply-To: <20130305211440.GA9929@banach>

On Tue, Mar 05, 2013 at 10:14:42PM +0100, Jose Garcia Juanino wrote:
> Is there any hook in Git similar to start-commit subversion hook? The
> requirements would be:
> 
> 1- A hook on the server side (as pre-receive)
> 2- It will execute the actions *before* the begin of transaction
> (pre-receive hook needs the references already pushed before).
> 
> For example, it would be useful to refuse a push if the server has a
> high load.

If you are using Gitolite[1] then a PRE_GIT trigger could do this.

With plain Git you can achieve the same by specifying a custom shell for
the users logging in and performing the custom check when
git-receive-pack is being executed.


[1] http://gitolite.com/gitolite

John

^ permalink raw reply

* Re: "git rebase" loses the additional changes in "evil" merges
From: Dale Worley @ 2013-03-05 21:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vtxoqx3s1.fsf@alter.siamese.dyndns.org>

> From: Junio C Hamano <gitster@pobox.com>
> 
> I think this is to be expected for "git rebase", as it does not even
> look at merges.  It is a way to find non-merge commits that haven't
> been applied yet, and apply them to the upstream to create a new
> linear history.

I disagree. "git rebase" is not characterized as a way to "find
non-merge commits that haven't been applied yet", but rather (as
described in the git-rebase manual page):
 
    git-rebase - Forward-port local commits to the updated upstream head

    All changes made by commits in the current branch but that are not
    in <upstream> are saved to a temporary area. [...]  The commits
    that were previously saved into the temporary area are then
    reapplied to the current branch, one by one, in order.

Now if you read far enough down the page, I'm sure it warns about
merge commits.  But the stated basic *intention* is to replicate the
existing branch, re-rooted at a new place on the upstream branch.

The current implementation fails this intention by losing changes made
in merges.  It fails this intention in a *dangerous* way by causing
changes to be lost without warning.

Dale

^ permalink raw reply

* Re: [PATCH/RFC] Changing submodule foreach --recursive to be depth-first, --parent option to execute command in supermodule as well
From: Phil Hord @ 2013-03-05 21:17 UTC (permalink / raw)
  To: Jens Lehmann
  Cc: Junio C Hamano, Eric Cousineau, Heiko Voigt, git@vger.kernel.org
In-Reply-To: <51365AB6.2010602@web.de>

On Tue, Mar 5, 2013 at 3:51 PM, Jens Lehmann <Jens.Lehmann@web.de> wrote:
> Am 05.03.2013 19:34, schrieb Junio C Hamano:
>> Eric Cousineau <eacousineau@gmail.com> writes:
>>> ...
>> I am not entirely convinced we would want --include-super in the
>> first place, though.  It does not belong to "submodule foreach";
>> it is doing something _outside_ the submoudules.
>
> I totally agree with that. First, adding --include-super does not
> belong into the --post-order patch at all, as that is a different
> topic (even though it belongs to the same use case Eric has). Also
> the reason why we are thinking about adding the --post-order option
> IMO cuts the other way for --include-super: It is so easy to do
> that yourself I'm not convinced we should add an extra option to
> foreach for that, especially as it has nothing to do with submodules.
> So I think we should just drop --include-super.

I agree it should not be part of this commit, but I've often found
myself in need of an --include-super switch.   To me,
git-submodule-foreach means "visit all my .git repos in this project
and execute $cmd".  It's a pity that the super-project is considered a
second-class citizen in this regard.

I have to do this sometimes:

   ${cmd} && git submodule foreach --recursive '${cmd}'

I often forget the first part in scripts, though, and I've seen others
do it too.  I usually create a function for it in git-heavy scripts.

In a shell, it usually goes like this:

   git submodule foreach --recursive '${cmd}'
   <up><home><del>{30-ish}<end><backspace><enter>

It'd be easier if I could just include a switch for this, and maybe
even create an alias for it.  But maybe this is different command
altogether.

^ permalink raw reply

* Git hook commit similar to subversion start-commit hook
From: Jose Garcia Juanino @ 2013-03-05 21:14 UTC (permalink / raw)
  To: git

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

Hello,

Is there any hook in Git similar to start-commit subversion hook? The
requirements would be:

1- A hook on the server side (as pre-receive)
2- It will execute the actions *before* the begin of transaction
(pre-receive hook needs the references already pushed before).

For example, it would be useful to refuse a push if the server has a
high load.

I have read man githook, but there is nothing similar.

Best regard, and excuse my poor english.


[-- Attachment #2: Type: application/pgp-signature, Size: 196 bytes --]

^ permalink raw reply

* Re: auto merge bug
From: Andreas Ericsson @ 2013-03-05 20:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, David Krmpotic, git
In-Reply-To: <7va9qhu1jk.fsf@alter.siamese.dyndns.org>

On 03/05/2013 07:47 PM, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
>> I'm also not sure how useful those really are in practice. I have not
>> used "union" myself ever. And in the example that started this thread, I
>> find the use of "union" slightly dubious.
> 
> Yeah, I do not think anybody sane used "union" outside toy examples.

I do, for lists used in tests or to generate perfect hashes from. It's
really quite handy for things like that but totally useless for any
type of multiline format, or even .ini style files unless you're very,
very careful with how you write them.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.

^ permalink raw reply

* Re: [PATCH/RFC] Changing submodule foreach --recursive to be depth-first, --parent option to execute command in supermodule as well
From: Jens Lehmann @ 2013-03-05 20:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Eric Cousineau, Heiko Voigt, git
In-Reply-To: <7vboaxu23y.fsf@alter.siamese.dyndns.org>

Am 05.03.2013 19:34, schrieb Junio C Hamano:
> Eric Cousineau <eacousineau@gmail.com> writes:
> 
>> Would these be the correct behaviors of Heiko's implementation?
> 
> I do not think Heiko already has an implementation, but let's try to
> see how each example makes sense.
> 
>> git submodule foreach # Empty command, pre-order
>> git submodule foreach --pre-order # Same behavior
>> git submodule foreach --post-order # Empty command, post-order
> 
> OK.  The last one shows "I am here" output differently from the
> other two, but otherwise they are all no-op.
> 
>> git submodule foreach 'frotz' # Do 'frotz' pre-order in each submodule
> 
> OK.  And it would be the same if you said either one of:
> 
> 	git submodule foreach --pre-order 'frotz'
> 	git submodule foreach --pre-order='frotz'
> 
>> git submodule foreach --post-order 'frotz' # Do 'frotz' post-order in
>> each submodule
> 
> OK.
> 
>> git submodule foreach --pre-order='frotz' --post-order='shimmy' # Do
>> 'frotz' pre-order and 'shimmy' post-order in each submodule
> 
> OK.
> 
>> git submodule foreach --post-order='shimmy' 'frotz' # Invalid usage of
>> the command
> 
> I would expect this to behave exactly the same as:
> 
> 	git submodule foreach \
>         	--post-order=shimmy \
>                 --pre-order=frotz
> 
>> git submodule foreach --post-order --pre-order #
> 
> I expect it to behave exactly the same as:
> 
> 	git submodule foreach --post-order=: --pre-order=:

I'd favor to just drop the --pre-order option and do this:

  foreach [--recursive] [--post-order <command>] [<command>]

Me thinks pre-order is a sane default and we shouldn't add an
explicit option for that. And even with current Git you can
simply give no command at all and it'll show you all the
submodules it enters without doing anything in them, so we'd
only need to add the --post-order handling anyway (and fix the
synopsis by adding square brackets around the command while at
it, as that is optional).

>> It should not be too hard to have this functionality affect the
>> --include-super command as well.
> 
> I would assume that
> 
> 	git submodule foreach --pre-order=A --post-order=B --include-super
> 
> would be identical to running
> 
> 	A &&
>         git submodule foreach --pre-order=A --post-order=B &&
>         B
>
> I am not entirely convinced we would want --include-super in the
> first place, though.  It does not belong to "submodule foreach";
> it is doing something _outside_ the submoudules.

I totally agree with that. First, adding --include-super does not
belong into the --post-order patch at all, as that is a different
topic (even though it belongs to the same use case Eric has). Also
the reason why we are thinking about adding the --post-order option
IMO cuts the other way for --include-super: It is so easy to do
that yourself I'm not convinced we should add an extra option to
foreach for that, especially as it has nothing to do with submodules.
So I think we should just drop --include-super.

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Jeff King @ 2013-03-05 19:27 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael Haggerty, git
In-Reply-To: <7v6215u05k.fsf@alter.siamese.dyndns.org>

On Tue, Mar 05, 2013 at 11:17:11AM -0800, Junio C Hamano wrote:

> I may have tentatively tagged the tip of 'master' as v1.8.2 in my
> private repository, started the integration testing, but may not be
> confident enough to push out the branch nor the tag yet.  I may have
> an experimental topic that I want to share with others before I am
> done with the release to unblock them, and the topic may build on
> the 'master' I may or may not want to redo before the release.
> 
> I can do so with "git push github jc/topic" (no --follow-tags).
> After doing such a "you may want to start with this" push, I can
> continue working on the release, and the 'master' branch may turn
> out to be good to go without redoing.
> 
> A later "git push github --follow-tags master" in such a case should
> send v1.8.2 out.  It is inexcuable to break it, saying "Oh, I've
> seen that commit already---it is part of the previous update to
> jc/topic".  That defeats the whole point of --follow-tags.

That depends on the specifics of the rule. If the rule is "any commit
that the server already has", then yes, it runs afoul of that problem.
But what if it is "any commit in the ref update being sent"? That is, we
would look at the range "origin/master..master" and send any tags that
point to commits in that range.

> The other "tags at the tip" is slightly less problematic than
> "ignore the commits the receiving end has already seen", but it will
> break if I tag the tip of 'maint' as v1.8.1.6, continue working
> without being able to push perhaps due to network disruption, and
> have already started building towards v1.8.1.7 when the network
> comes back.  'maint' may be past v1.8.1.6 and its tip won't be
> pointing at that tag, but it still is missing from the public
> repository.

Right, I think "tags at the tip" is too likely to miss things you did
want to send.

> While I agree with your goal to make it safer to use "push", both
> "ignore commits that the receiving end already saw" and "only look
> at the commits at the tip being sent" castrate the option too much
> to the point that it is meaningless.  The whole point of asking
> explicitly with the "--follow-tags" option to "push" to push out
> relevant tags is, eh, to push out relevant tags.  I do not think it
> is magical at all.  "backfill" is an integral part of the option.

I know, and I'm willing to accept that the right resolution is "we
should not have this feature" (or possibly "the documentation must warn
about caveats of the feature). I'm just worried about it accidentally
being misused and causing problems.

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Junio C Hamano @ 2013-03-05 19:17 UTC (permalink / raw)
  To: Jeff King; +Cc: Michael Haggerty, git
In-Reply-To: <20130305182255.GB10928@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> Yeah, I think that is another sensible variant. It does not really
> "backfill" in the way that Junio's patch does (e.g., if you forgot to
> push out v1.6 to a remote 2 weeks ago and now you are pushing out v1.7,
> Junio's patch will magically fill it in).

I may have tentatively tagged the tip of 'master' as v1.8.2 in my
private repository, started the integration testing, but may not be
confident enough to push out the branch nor the tag yet.  I may have
an experimental topic that I want to share with others before I am
done with the release to unblock them, and the topic may build on
the 'master' I may or may not want to redo before the release.

I can do so with "git push github jc/topic" (no --follow-tags).
After doing such a "you may want to start with this" push, I can
continue working on the release, and the 'master' branch may turn
out to be good to go without redoing.

A later "git push github --follow-tags master" in such a case should
send v1.8.2 out.  It is inexcuable to break it, saying "Oh, I've
seen that commit already---it is part of the previous update to
jc/topic".  That defeats the whole point of --follow-tags.

The other "tags at the tip" is slightly less problematic than
"ignore the commits the receiving end has already seen", but it will
break if I tag the tip of 'maint' as v1.8.1.6, continue working
without being able to push perhaps due to network disruption, and
have already started building towards v1.8.1.7 when the network
comes back.  'maint' may be past v1.8.1.6 and its tip won't be
pointing at that tag, but it still is missing from the public
repository.

While I agree with your goal to make it safer to use "push", both
"ignore commits that the receiving end already saw" and "only look
at the commits at the tip being sent" castrate the option too much
to the point that it is meaningless.  The whole point of asking
explicitly with the "--follow-tags" option to "push" to push out
relevant tags is, eh, to push out relevant tags.  I do not think it
is magical at all.  "backfill" is an integral part of the option.

^ permalink raw reply

* Re: auto merge bug
From: Junio C Hamano @ 2013-03-05 18:47 UTC (permalink / raw)
  To: Jeff King; +Cc: David Krmpotic, git
In-Reply-To: <20130305175904.GC9379@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> I'm also not sure how useful those really are in practice. I have not
> used "union" myself ever. And in the example that started this thread, I
> find the use of "union" slightly dubious.

Yeah, I do not think anybody sane used "union" outside toy examples.
IIRC, it was originally done as a "if you want a GIGO, here it is,
go hang yourself." response to "I am too lazy to resolve conflicts
myself, Git should let me take both sides blindly."

^ permalink raw reply

* Re: [PATCH/RFC] Changing submodule foreach --recursive to be depth-first, --parent option to execute command in supermodule as well
From: Junio C Hamano @ 2013-03-05 18:34 UTC (permalink / raw)
  To: Eric Cousineau; +Cc: Heiko Voigt, Jens Lehmann, git
In-Reply-To: <CA+aSAWvQj2wuJX3ENNn7n_pMJjA6nauve5BLRugiTuhWN25Ctg@mail.gmail.com>

Eric Cousineau <eacousineau@gmail.com> writes:

> Would these be the correct behaviors of Heiko's implementation?

I do not think Heiko already has an implementation, but let's try to
see how each example makes sense.

> git submodule foreach # Empty command, pre-order
> git submodule foreach --pre-order # Same behavior
> git submodule foreach --post-order # Empty command, post-order

OK.  The last one shows "I am here" output differently from the
other two, but otherwise they are all no-op.

> git submodule foreach 'frotz' # Do 'frotz' pre-order in each submodule

OK.  And it would be the same if you said either one of:

	git submodule foreach --pre-order 'frotz'
	git submodule foreach --pre-order='frotz'

> git submodule foreach --post-order 'frotz' # Do 'frotz' post-order in
> each submodule

OK.

> git submodule foreach --pre-order='frotz' --post-order='shimmy' # Do
> 'frotz' pre-order and 'shimmy' post-order in each submodule

OK.

> git submodule foreach --post-order='shimmy' 'frotz' # Invalid usage of
> the command

I would expect this to behave exactly the same as:

	git submodule foreach \
        	--post-order=shimmy \
                --pre-order=frotz

> git submodule foreach --post-order --pre-order #

I expect it to behave exactly the same as:

	git submodule foreach --post-order=: --pre-order=:

> It should not be too hard to have this functionality affect the
> --include-super command as well.

I would assume that

	git submodule foreach --pre-order=A --post-order=B --include-super

would be identical to running

	A &&
        git submodule foreach --pre-order=A --post-order=B &&
        B

I am not entirely convinced we would want --include-super in the
first place, though.  It does not belong to "submodule foreach";
it is doing something _outside_ the submoudules.

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Jeff King @ 2013-03-05 18:22 UTC (permalink / raw)
  To: Michael Haggerty; +Cc: Junio C Hamano, git
In-Reply-To: <5135DBE5.6080909@alum.mit.edu>

On Tue, Mar 05, 2013 at 12:49:57PM +0100, Michael Haggerty wrote:

> > One obvious alternative is only to push annotated tags with this
> > feature. That has the downside of not matching fetch's behavior, as well
> > as withholding the feature from people whose workflow uses only
> > unannotated tags.
> > 
> > Another alternative would be to change the inclusion rule from
> > "reachable" to "points at the tip of something being sent". But then we
> > lose the feature that it would backfill any old tags the remote happens
> > to be missing.
> 
> I have no opinion on this matter, but ISTM that another obvious
> alternative would be to push tags that point at *any* commits that are
> being sent (not just at the tip), but not those that point to older
> commits already known to the server.  This would reduce the potential
> for accidental pushes of "distant" tags.

Yeah, I think that is another sensible variant. It does not really
"backfill" in the way that Junio's patch does (e.g., if you forgot to
push out v1.6 to a remote 2 weeks ago and now you are pushing out v1.7,
Junio's patch will magically fill it in). But I do not see a huge value
in backfilling. It is anyone's guess whether you simply forgot to push
out v1.6 or whether you intended to hold it back. And I'd rather err on
the side of not-pushing because of the difficulty of retraction.

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Jeff King @ 2013-03-05 18:18 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vobexu30n.fsf@alter.siamese.dyndns.org>

On Tue, Mar 05, 2013 at 10:15:20AM -0800, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > But I wonder if fetching and pushing are different in that respect. You
> > are (usually) fetching from a public publishing point, and it is assumed
> > that whatever is there is useful for sharing. The only reason to limit
> > it is to save time transferring objects the user does not want.
> 
> There are those who have to emulate "git fetch" with a reverse "git
> push" (or vice versa) due to network connection limitations, so I do
> not think hardcoding such a policy decision in the direction is
> necessarily a good idea.

Yeah, but I think it makes sense to optimize the defaults for the common
cases, and let people doing unusual things override the behavior via
options (or even config).

Don't get me wrong, I think there is value in the simplicity of having
the push/fetch transactions be as symmetric as possible. But given the
potentially high cost of a mistaken push (i.e., retracting published
history can be embarrassing or complicated), there's also value in safe
defaults. And I feel like we've already gone in that direction with the
default refspecs being different between fetch and push.

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Junio C Hamano @ 2013-03-05 18:15 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20130305172233.GA9379@sigill.intra.peff.net>

Jeff King <peff@peff.net> writes:

> But I wonder if fetching and pushing are different in that respect. You
> are (usually) fetching from a public publishing point, and it is assumed
> that whatever is there is useful for sharing. The only reason to limit
> it is to save time transferring objects the user does not want.

There are those who have to emulate "git fetch" with a reverse "git
push" (or vice versa) due to network connection limitations, so I do
not think hardcoding such a policy decision in the direction is
necessarily a good idea.

> ... But I also don't want to introduce a feature
> that causes people to accidentally publish cruft. It may not be a
> problem in practice; I'm just thinking out loud at this point.

Likewise.

^ permalink raw reply

* Re: auto merge bug
From: Jeff King @ 2013-03-05 17:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: David Krmpotic, git
In-Reply-To: <7vtxopvoky.fsf@alter.siamese.dyndns.org>

On Tue, Mar 05, 2013 at 07:44:13AM -0800, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > I think the merge will produce the results you are looking for. This
> > would have to be configurable, though, as it is a regression for
> > existing users of "union", which would want the duplicate-line
> > suppression (or maybe not; it will only catch such duplicates at the
> > beginning and end of the conflict hunk, so maybe it is sane to always
> > ask "union" to keep all lines).
> 
> The original use-case example of "union" was to merge two shopping
> lists (e.g. I add "bread" and "orange juice" to remind me that we
> need to buy these things, while my wife adds "bread" and "butter").
> 
> We do not necessarily want to end up with a shopping list to buy two
> loaves of bread.  When the user verifies and fixes up the result, we
> can keep the current behaviour and those who want to re-dup can add
> one back, or we can change the behaviour to leave the duplicates and
> those who do not want to see duplicates can remove them manually.
> 
> Given that the caveat you quoted already tells the user to verify
> the result and not to use it without understanding its implications,
> I think it technically is fine either way (read: keeping duplicates
> is not a clearly superiour solution). So let's leave it as-is.

My problem with the current behavior is that it is not predictable
whether it will de-dup or not. If your shopping lists are:

  bread
  orange juice

  bread
  butter

it works; you get only one bread. If they are:

  milk
  bread
  orange juice

  beer
  bread
  butter

you get two. It depends on the exact behavior of the XDL_MERGE_ZEALOUS
flag. What I'd propose is two different drivers:

  1. Find conflicts via 3-way merge, and include both sides of the
     conflict verbatim. Do not use XDL_MERGE_ZEALOUS, as it is more
     important to retain items from both sides (in their original order)
     than it is to remove duplicates.

  2. A true line-based union, which should act like "cat $ours $theirs |
     sort | uniq". That is what you want for the shopping list example,
     I think (you could also preserve existing ordering with a lookup
     table, though I prefer clobbering the ordering; the ordering of
     resolved conflicts will be arbitrary anyway, so it makes it clear
     from the outset that you should not use this driver if your content
     is not really a set (in the mathematical sense) of lines).

     You could also have sets of other objects (e.g., blank-line
     delimited paragraphs, changelog entries, etc). But you would need
     some way to specify the parsing then[1].

I'm not sure which should be called "union". The first one would still
need careful examination of the result. The second one should always be
correct, but only because it is limited to a much more constrained
problem.

I'm also not sure how useful those really are in practice. I have not
used "union" myself ever. And in the example that started this thread, I
find the use of "union" slightly dubious. I do not even know how it
would react to a line _changing_, or other complicated edit. Short of a
specialized XML-aware merge driver, using XDL_MERGE_ZEALOUS and kicking
the result out to the user (i.e., what the default merge driver does)
seems like the only sane thing, even if it is more work at merge time.

-Peff

[1] Some of this is fairly easy to do with perl one-liners (e.g., "perl
   -00 -ne 'print unless $h{$_}++" for paragraph mode), so maybe it is
   just an education/documentation issue. I dunno. I have always been
   happy enough with the stock merge.

^ permalink raw reply

* Re: [PATCH] help: show manpage for aliased command on git <alias> --help
From: Jeff King @ 2013-03-05 17:38 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Jonathan Nieder, H.Merijn Brand
In-Reply-To: <1362494681-11419-1-git-send-email-avarab@gmail.com>

On Tue, Mar 05, 2013 at 02:44:41PM +0000, Ævar Arnfjörð Bjarmason wrote:

> Change the semantics of "git <alias> --help" to show the help for the
> command <alias> is aliased to, instead of just saying:
> 
>     `git <alias>' is aliased to `<whatever>'
> 
> E.g. if you have "checkout" aliased to "co" you won't get:
> 
>     $ git co --help
>     `git co' is aliased to `checkout'
> 
> But will instead get the manpage for git-checkout. The behavior this
> is replacing was originally added by Jeff King in 2156435. I'm
> changing it because of this off-the-cuff comment on IRC:
> 
>     14:27:43 <@Tux> git can be very unhelpful, literally:
>     14:27:46 <@Tux> $ git co --help
>     14:27:46 <@Tux> `git co' is aliased to `checkout'
>     14:28:08 <@Tux> I know!, gimme the help for checkout, please
> 
> And because I also think it makes more sense than showing you what the
> thing is aliased to.

In this simple case, I think it is helpful to show the "checkout"
manpage, because there is no other information to give (and by showing
the checkout manpage, you implicitly indicate that "co" maps to
"checkout").

But like others, I am concerned about the other cases, where there is no
manpage, it is not a git command with a manpage, or it is a git command
with options.  You are losing useful information that is currently given
to the user in all but the single-word case.

In an ideal world, we could say "here is how the alias expands, and by
the way, here is the manpage for the expanded command". And obviously
just omit the latter part when there is no such page. But we are relying
on external programs to do the presentation and paging. Doing the
C equivalent of:

  echo "'git co' is aliased to 'checkout'" &&
  man checkout

does not quite work, because "man" will start a pager. We can run our
own pager (which should suppress man's invocation), but that is a
regression for anyone who uses MANPAGER.

The user may also be using help.format to use something besides man. If
help.format is set to "html", we will spawn a browser. In that case we
can still output the alias information, but it may or may not be seen
(though come to think of it, that is probably already a problem for "git
help <alias>" on Windows systems, or anybody invoking git help from a
GUI porcelain).

So I'd only be in favor of this patch if it managed to avoid information
loss in the more complicated cases. And I'm not sure how best to do
that. The "only trigger for a single-word alias" suggestion seems like
the least ugly to me.

-Peff

^ permalink raw reply

* Re: [PATCH 2/2] push: --follow-tag
From: Jeff King @ 2013-03-05 17:22 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlia1vnwq.fsf@alter.siamese.dyndns.org>

On Tue, Mar 05, 2013 at 07:58:45AM -0800, Junio C Hamano wrote:

> > This will find anything under refs/tags, including annotated and
> > non-annotated tags. I wonder if it is worth making a distinction. In
> > many workflows, unannotated tags should not be leaked out to public
> > repos. But because this feature finds any reachable tags, it will push a
> > tag you made a long time ago as a bookmarker on some part of the history
> > unrelated to the release you are making now.
> 
> What does the auto-follow feature of "git fetch" do currently?
> Whatever we do here on the "git push" side should match it.

It fetches anything in refs/tags, unannotated or not. And that is
certainly a point in favor of "git push" doing the same.

But I wonder if fetching and pushing are different in that respect. You
are (usually) fetching from a public publishing point, and it is assumed
that whatever is there is useful for sharing. The only reason to limit
it is to save time transferring objects the user does not want.

But for "push", you are on the publishing side, which usually means you
need to be a little more careful. It is not just an optimization; it is
about deciding what should be shared. You do not want to accidentally
push cruft or work in progress in your private repository. I think it's
the same logic that leads us to fetch "refs/heads/*" by default, but
only push "matching" (or more recently "HEAD").

> If somebody wants to add some form of filtering mechanism based on
> the tagname (e.g. '--auto-follow-tags=v[0-9]*'), I would not have a
> strong objection to it, but I think that is something we should do
> on top and consistently between fetch and push.  I am not thrilled
> by the idea of conflating annotated-ness and the public-ness of
> tags.

I don't like it either. But I also don't want to introduce a feature
that causes people to accidentally publish cruft. It may not be a
problem in practice; I'm just thinking out loud at this point.

-Peff

^ 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