* Re: [PATCH v5 11/15] remote-testgit: make clear the 'done' feature
From: Felipe Contreras @ 2012-11-12 16:40 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Max Horn, git, Junio C Hamano, Johannes Schindelin, Jeff King,
Sverre Rabbelier, Brandon Casey, Brandon Casey, Ilari Liusvaara,
Pete Wyckoff, Ben Walton, Matthieu Moy, Julian Phillips
In-Reply-To: <20121112154515.GB3546@elie.Belkin>
On Mon, Nov 12, 2012 at 4:45 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Max Horn wrote:
>
>> Aha, now I understand what this patch is about. So I would suggest
>> this alternate commit message:
>>
>> remote-testgit: make it explicit clear that we use the 'done' feature
>>
>> Previously we relied on passing '--use-done-feature ' to git
>> fast-export, which is easy to miss when looking at this script.
>
> I'm not immediately sure I agree this is even a problem. Is the point
> that other fast-import frontends do not have a --use-done-feature
> switch,
You mean other fast-exports.
And what other fast-exports? Most remote helpers don't use an external
fast-export tool, and the only I know that used one is the one I wrote
(and is now deprecated) that used bzr fast-export, and no, that one
didn't support the done feature.
Most remote helpers would probably be doing the equivalent of
fast-export themselves.
> so a typical remote helper has to do that work itself, and the
> sample "testgit" remote helper would be a more helpful example by
> doing that work itself?
Yes.
> The idea behind --use-done-feature is that if fast-export exits early
> for some reason and its output is going to a pipe then at least the
> stream will be malformed, making it easier to catch errors. So there
> is something to be weighed here: is it more important to illustrate
> how to make your fast-export tool's output prefix-free,
What fast-export tool?
This is a remote helper.
> or is it more
> important to illustrate how to work around a fast-export tool that
> doesn't support that feature?
Ditto.
If you want to launch a campaign of adding the 'done' feature to
whatever fast-export tools are out there (that I'm not aware of), go
ahead, but this is about remote helpers, most (all?) of which would
not use a fast-export tool to achieve the export, but do it
themselves.
Cheers.
--
Felipe Contreras
^ permalink raw reply
* splitting off shell test framework
From: Adam Spiers @ 2012-11-12 16:37 UTC (permalink / raw)
To: Git Mailing List
Hi all,
I've been pretty impressed with git's test framework, and I'm not
aware of many other (decent) shell-based test frameworks out there.
(One that springs to mind is the one used by rvm, but last time I
looked - admittedly a while ago now - it had limitations).
Recently a situation arose where I craved the ability to test
something via shell. I did a quick proof of concept and successfully
extracted out the non-git-specific bits of git's test framework to be
used to test something entirely unrelated to git:
https://github.com/aspiers/shell-env/tree/master/t
As it turned out to be fairly easy, I was wondering if there would be
any interest in doing this more formally, i.e. splitting off the
framework so that it could be used and improved outside the scope of
git development? Of course this would pose the question how git would
consume this new project without any risk of destabilisation. I'm
guessing that simply using a git submodule would solve the problem,
but ICBW ...
Just an idea. Interesting, or terrible? :)
Regards,
Adam
^ permalink raw reply
* [regression] Newer gits cannot clone any remote repos
From: Douglas Mencken @ 2012-11-12 16:32 UTC (permalink / raw)
To: git
*Any* git clone fails with:
fatal: premature end of pack file, 106 bytes missing
fatal: index-pack failed
At first, I tried 1.8.0, and it failed. Then I tried to build 1.7.10.5
then, and it worked. Then I tried 1.7.12.2, but it fails the same way
as 1.8.0.
So I decided to git bisect.
b8a2486f1524947f232f657e9f2ebf44e3e7a243 is the first bad commit
``index-pack: support multithreaded delta resolving''
--------------------------------------------------------------------------------
b8a2486f1524947f232f657e9f2ebf44e3e7a243 is the first bad commit
commit b8a2486f1524947f232f657e9f2ebf44e3e7a243
Author: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date: Sun May 6 19:31:55 2012 +0700
index-pack: support multithreaded delta resolving
This puts delta resolving on each base on a separate thread, one base
cache per thread. Per-thread data is grouped in struct thread_local.
When running with nr_threads == 1, no pthreads calls are made. The
system essentially runs in non-thread mode.
An experiment on a Xeon 24 core machine with git.git shows that
performance does not increase proportional to the number of cores. So
by default, we use maximum 3 cores. Some numbers with --threads from 1
to 16:
1..4
real 0m8.003s 0m5.307s 0m4.321s 0m3.830s
user 0m7.720s 0m8.009s 0m8.133s 0m8.305s
sys 0m0.224s 0m0.372s 0m0.360s 0m0.360s
5..8
real 0m3.727s 0m3.604s 0m3.332s 0m3.369s
user 0m9.361s 0m9.817s 0m9.525s 0m9.769s
sys 0m0.584s 0m0.624s 0m0.540s 0m0.560s
9..12
real 0m3.036s 0m3.139s 0m3.177s 0m2.961s
user 0m8.977s 0m10.205s 0m9.737s 0m10.073s
sys 0m0.596s 0m0.680s 0m0.684s 0m0.680s
13..16
real 0m2.985s 0m2.894s 0m2.975s 0m2.971s
user 0m9.825s 0m10.573s 0m10.833s 0m11.361s
sys 0m0.788s 0m0.732s 0m0.904s 0m1.016s
On an Intel dual core and linux-2.6.git
1..4
real 2m37.789s 2m7.963s 2m0.920s 1m58.213s
user 2m28.415s 2m52.325s 2m50.176s 2m41.187s
sys 0m7.808s 0m11.181s 0m11.224s 0m10.731s
Thanks Ramsay Jones for troubleshooting and support on MinGW platform.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
:040000 040000 e5597fe041cd7985648030c8cf1cc35ea57786bb
6e64f3e76b350c04c9d0c435e0a53b89e0821339 M Documentation
:100644 100644 cf2c40b44f8383d002235400660d76ef7f6de33c
e41955ff955693ddc78722c14fff2a6e98663a46 M Makefile
:040000 040000 1e6b5ac5f11bf7ba3eff7b5be4410bad379feee6
85bc79414f00b7fc3698c069161ea10039641082 M builtin
:040000 040000 04916545d959c8af772cd3a2de5e6b470529bea1
325c8c748dd41d469135db84c7621d8225cc1cdd M t
$ git bisect log
git bisect start
# bad: [d8cf053dacb4f78920c112d10c7be21e4f5a5817] Git 1.7.12.2
git bisect bad d8cf053dacb4f78920c112d10c7be21e4f5a5817
# good: [785ee4960c3d334cbc2b17ab74d2cebdf1b4db64] Git 1.7.10.5
git bisect good 785ee4960c3d334cbc2b17ab74d2cebdf1b4db64
# bad: [d692d34653f74be6b16add3e993e957f33fe049b] Merge branch
'rs/git-blame-mapcar-mapc'
git bisect bad d692d34653f74be6b16add3e993e957f33fe049b
# good: [73ff8cf784b6ee447072fad6c06fd0eef0e9c9f6] Merge branch
'lp/diffstat-with-graph'
git bisect good 73ff8cf784b6ee447072fad6c06fd0eef0e9c9f6
# bad: [7903e66a3e10e98f29fc9524c13274376bae5303] Merge branch
'mh/test-keep-prove-cache'
git bisect bad 7903e66a3e10e98f29fc9524c13274376bae5303
# good: [499e7b31509cfbb59dcb2a046f8e2fd1a3e73d6f] Merge branch
'jc/install-no-hardlinks'
git bisect good 499e7b31509cfbb59dcb2a046f8e2fd1a3e73d6f
# bad: [2e464dd5b220d4d2d8a16d5c43efe7af3c9adda9] Merge branch
'rs/xdiff-lose-emit-func'
git bisect bad 2e464dd5b220d4d2d8a16d5c43efe7af3c9adda9
# good: [8fbe0db4fce68ed8239742b14e9d77d45201870b] Merge branch
'master' of git://github.com/git-l10n/git-po
git bisect good 8fbe0db4fce68ed8239742b14e9d77d45201870b
# bad: [2b26b65f9abc77c4af87626452005a73edda0c8f] git-svn: clarify
the referent of dcommit's optional argument
git bisect bad 2b26b65f9abc77c4af87626452005a73edda0c8f
# bad: [cc13431a49800a6a1d2b7ff0b94f67da0fecdbab] Merge branch
'nd/threaded-index-pack'
git bisect bad cc13431a49800a6a1d2b7ff0b94f67da0fecdbab
# bad: [b8a2486f1524947f232f657e9f2ebf44e3e7a243] index-pack:
support multithreaded delta resolving
git bisect bad b8a2486f1524947f232f657e9f2ebf44e3e7a243
# good: [5272f75587abb4cb396059ecbf1a6130bb2e69d3] index-pack:
restructure pack processing into three main functions
git bisect good 5272f75587abb4cb396059ecbf1a6130bb2e69d3
$ git bisect reset
Previous HEAD position was 5272f75... index-pack: restructure pack
processing into three main functions
HEAD is now at d8cf053... Git 1.7.12.2
^ permalink raw reply
* Re: [PATCH v5 15/15] fast-export: don't handle uninteresting refs
From: Felipe Contreras @ 2012-11-12 16:28 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Johannes Schindelin, Max Horn, Jeff King,
Sverre Rabbelier, Brandon Casey, Brandon Casey, Jonathan Nieder,
Ilari Liusvaara, Pete Wyckoff, Ben Walton, Matthieu Moy,
Julian Phillips, Felipe Contreras
In-Reply-To: <1352642392-28387-16-git-send-email-felipe.contreras@gmail.com>
On Sun, Nov 11, 2012 at 2:59 PM, Felipe Contreras
<felipe.contreras@gmail.com> wrote:
> They have been marked as UNINTERESTING for a reason, lets respect that.
>
> Currently the first ref is handled properly, but not the rest, so:
>
> % git fast-export master ^master
>
> Would currently throw a reset for master (2nd ref), which is not what we
> want.
>
> % git fast-export master ^foo ^bar ^roo
> % git fast-export master salsa..tacos
>
> Even if all these refs point to the same object; foo, bar, roo, salsa,
> and tacos would all get a reset, and to a non-existing object (invalid
> mark :0).
>
> And even more, it would only happen if the ref is pointing to exactly
> the same commit, but not otherwise:
>
> % git fast-export ^next next
> reset refs/heads/next
> from :0
>
> % git fast-export ^next next^{commit}
> # nothing
> % git fast-export ^next next~0
> # nothing
> % git fast-export ^next next~1
> # nothing
> % git fast-export ^next next~2
> # nothing
>
> The reason this happens is that before traversing the commits,
> fast-export checks if any of the refs point to the same object, and any
> duplicated ref gets added to a list in order to issue 'reset' commands
> after the traversing. Unfortunately, it's not even checking if the
> commit is flagged as UNINTERESTING. The fix of course, is to do
> precisely that.
>
> The current behavior is most certainly not what we want. After this
> patch, nothing gets exported, because nothing was selected (everything
> is UNINTERESTING).
>
> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
And here's yet another reason why this is obviously correct that I just found:
% git fast-export --use-done-feature
--{import,export}-marks=.git/hg/origin/marks-git
^refs/hg/origin/branches/default ^refs/hg/origin/bookmarks/test6
refs/heads/test6 ^refs/hg/origin/bookmarks/master
^refs/hg/origin/bookmarks/test
feature done
reset refs/hg/origin/bookmarks/test
from :4
reset refs/heads/test6
from :14
done
What is that refs/hg/origin/bookmarks/test doing there?
transport-helper does use a fast-export command like that to specify
precisely what refs should be *IGNORED*, and yet fast-export will
throw a reset for a ref that has been marked as UNINTERESTING. So, the
receiving end in the helper will see a reset for a ref that it
explicitly said was marked as outside it's refspec realm:
refspec refs/heads/*:refs/hg/origin/bookmarks/*
What is remote-hg supposed to do with 'refs/hg/origin/bookmarks/test'?
There's nothing that can be done, it's a bug in fast-export that such
a thing was exported in the first place. And the reason it happens is
that another ref happens to be pointing to the same object, (in this
case refs/hg/origin/branches/default)
So yeah, the patch is good.
Of course, transport-helper shouldn't even be specifying the negative
(^) refs, but that's another story.
Cheers.
--
Felipe Contreras
^ permalink raw reply
* Re: [PATCH v5 11/15] remote-testgit: make clear the 'done' feature
From: Jonathan Nieder @ 2012-11-12 15:45 UTC (permalink / raw)
To: Max Horn
Cc: Felipe Contreras, git, Junio C Hamano, Johannes Schindelin,
Jeff King, Sverre Rabbelier, Brandon Casey, Brandon Casey,
Ilari Liusvaara, Pete Wyckoff, Ben Walton, Matthieu Moy,
Julian Phillips
In-Reply-To: <EA56F0CC-7C93-491F-A076-4A1AA9593ED0@quendi.de>
Max Horn wrote:
> Aha, now I understand what this patch is about. So I would suggest
> this alternate commit message:
>
> remote-testgit: make it explicit clear that we use the 'done' feature
>
> Previously we relied on passing '--use-done-feature ' to git
> fast-export, which is easy to miss when looking at this script.
I'm not immediately sure I agree this is even a problem. Is the point
that other fast-import frontends do not have a --use-done-feature
switch, so a typical remote helper has to do that work itself, and the
sample "testgit" remote helper would be a more helpful example by
doing that work itself?
The idea behind --use-done-feature is that if fast-export exits early
for some reason and its output is going to a pipe then at least the
stream will be malformed, making it easier to catch errors. So there
is something to be weighed here: is it more important to illustrate
how to make your fast-export tool's output prefix-free, or is it more
important to illustrate how to work around a fast-export tool that
doesn't support that feature? The answer is not immediately obvious
to me. A good description could provide context to make it obvious.
Hoping that clarifies,
Jonathan
^ permalink raw reply
* Re: [PATCH] Documentation/log: fix description of format.pretty
From: Jonathan Nieder @ 2012-11-12 15:38 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: Git List
In-Reply-To: <CALkWK0nR_9mWDKzKygR379x3L=d4bGKKo27AP-2Y=+coc7H+sQ@mail.gmail.com>
Ramkumar Ramachandra wrote:
> Oops, I read about `--pretty` in pretty-formats.txt and didn't realize
> that `--format` existed. However, your patch is still wrong because
> there seems to be a subtle (and confusing) difference between
> `--pretty` and `--format`. In the latter, you can't omit the format,
> and expect it to be picked up from format.pretty:
>
> $ git log --format
> fatal: unrecognized argument: --format
You can do
$ git log
and format.pretty will still take effect. In other words, setting
format.pretty to "foo" is somewhat like making
$ git log
do
$ git log --format=foo
which is what the text is supposed to explain. It is based on the
following text from Documentation/config.txt:
format.pretty::
The default pretty format for log/show/whatchanged command,
See linkgit:git-log[1], linkgit:git-show[1],
linkgit:git-whatchanged[1].
I do imagine it can be made clearer. s/--format/--pretty/ does not go
far enough --- it only replaces one confusing explanation with
another.
Hoping that clarifies,
Jonathan
^ permalink raw reply
* RE: git-svn with ignore-paths misses/skips some revisions during fetch
From: McHenry, Matt @ 2012-11-12 15:00 UTC (permalink / raw)
To: git@vger.kernel.org; +Cc: Enrico Weigelt
In-Reply-To: <be90fa6b-3927-47cb-9306-6dbb7bac2c04@zcs>
Enrico asked:
> Could it be that certain files spent parts of their historical lifetime
> inside the ignored paths ?
I left out one possibly important piece of information: My initial 'git svn fetch' used '-r' to "cauterize" the history, both because there is a lot of it (almost 12 years) and because the repository was reorganized significantly after a cvs -> svn migration. The first revision I have is r83875:
$ git log --max-parents=0 --all --date-order | tail -n 1
git-svn-id: svn://dev.carnegielearning.com/trunk@83875 752fcc94-cd22-0410-baa8-ef54ac2c6973
So to answer Enrico's question: Prior to the initial revision that was fetched into git, these files did live in a different top-level directory. However it's not one that's matched by the 'ignore-paths' regex. Here's one example:
$ svn log -v svn://dev/branches/localization-merge/buildprocess/antfiles/dmg.xml | grep /dmg.xml | uniq -c
9 M /branches/localization-merge/buildprocess/antfiles/dmg.xml
35 M /trunk/buildprocess/antfiles/dmg.xml
1 A /trunk/buildprocess/antfiles/dmg.xml (from /trunk/buildprocess/assemble-support/dmg.xml:48305)
1 D /trunk/buildprocess/assemble-support/dmg.xml
57 M /trunk/assemble-support/dmg.xml
1 A /trunk/assemble-support/dmg.xml
Here are the svn revisions that explain the transition from 'assemble-support' to 'buildprocess/assemble-support', just after the cvs -> svn migration.
------------------------------------------------------------------------
r48303 | matt | 2006-11-27 14:56:10 -0500 (Mon, 27 Nov 2006) | 1 line
Changed paths:
D /old-trunk/assemble-support
A /trunk/buildprocess/assemble-support (from /old-trunk/assemble-support:48302)
moving old assemble-support into new buildprocess
------------------------------------------------------------------------
r48248 | matt | 2006-11-22 13:41:42 -0500 (Wed, 22 Nov 2006) | 1 line
Changed paths:
A /old-trunk (from /trunk:48247)
D /trunk
moving old trunk out of the way
------------------------------------------------------------------------
Matt McHenry
Software Developer
Carnegie Learning, Inc.
(888) 851-7094 x150 toll free
(412) 690-2444 fax
mmchenry@carnegielearning.com
www.carnegielearning.com
Decision 2012: Election Math | Engaging Video Content | FREE Interactive Math Problems
http://www.nbclearn.com/portal/site/learn/decision2012
^ permalink raw reply
* [PATCHv3] replace: parse revision argument for -d
From: Michael J Gruber @ 2012-11-12 14:18 UTC (permalink / raw)
To: git; +Cc: Jeff King, Junio C Hamano
In-Reply-To: <50A0B896.8050700@drmicha.warpmail.net>
'git replace' parses the revision arguments when it creates replacements
(so that a sha1 can be abbreviated, e.g.) but not when deleting
replacements.
Make it parse the argument to 'replace -d' in the same way.
Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
Notes:
v3 safeguards the hex buffer against reuse
builtin/replace.c | 16 ++++++++++------
t/t6050-replace.sh | 11 +++++++++++
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/builtin/replace.c b/builtin/replace.c
index e3aaf70..33e6ec3 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -46,24 +46,28 @@ typedef int (*each_replace_name_fn)(const char *name, const char *ref,
static int for_each_replace_name(const char **argv, each_replace_name_fn fn)
{
- const char **p;
+ const char **p, *q;
char ref[PATH_MAX];
int had_error = 0;
unsigned char sha1[20];
for (p = argv; *p; p++) {
- if (snprintf(ref, sizeof(ref), "refs/replace/%s", *p)
- >= sizeof(ref)) {
- error("replace ref name too long: %.*s...", 50, *p);
+ q = *p;
+ if (get_sha1(q, sha1)) {
+ error("Failed to resolve '%s' as a valid ref.", q);
had_error = 1;
continue;
}
+ q = sha1_to_hex(sha1);
+ snprintf(ref, sizeof(ref), "refs/replace/%s", q);
+ /* read_ref() may reuse the buffer */
+ q = ref + strlen("refs/replace/");
if (read_ref(ref, sha1)) {
- error("replace ref '%s' not found.", *p);
+ error("replace ref '%s' not found.", q);
had_error = 1;
continue;
}
- if (fn(*p, ref, sha1))
+ if (fn(q, ref, sha1))
had_error = 1;
}
return had_error;
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 5c87f28..decdc33 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -140,6 +140,17 @@ test_expect_success '"git replace" replacing' '
test "$HASH2" = "$(git replace)"
'
+test_expect_success '"git replace" resolves sha1' '
+ SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&
+ git replace -d $SHORTHASH2 &&
+ git replace $SHORTHASH2 $R &&
+ git show $HASH2 | grep "O Thor" &&
+ test_must_fail git replace $HASH2 $R &&
+ git replace -f $HASH2 $R &&
+ test_must_fail git replace -f &&
+ test "$HASH2" = "$(git replace)"
+'
+
# This creates a side branch where the bug in H2
# does not appear because P2 is created by applying
# H2 and squashing H5 into it.
--
1.8.0.311.gdd08018
^ permalink raw reply related
* Re: Help requested - trying to build a tool doing whole-tree commits
From: ydirson @ 2012-11-12 13:11 UTC (permalink / raw)
To: Eric S. Raymond; +Cc: git
In-Reply-To: <931951238.74665890.1352725212354.JavaMail.root@zimbra39-e7.priv.proxad.net>
esr:
>Junio C Hamano <gitster <at> pobox.com>:
>> Perhaps not exactly what you are looking for, but don't we have
>> import-tar somewhere in contrib/fast-import hierarchy (sorry, not on
>> a machine yet, and I cannot give more details).
>
>If I recall correctly, that can only be used for original import.
You may find my (old) ag-import-patch tool useful. Although the name does not
imply it, it allows to import a series of releases that can be available either as
tarballs or as patches.
http://ydirson.free.fr/soft/git/argit.git/
There's not much doc in there, and not so much I can remember myself from the short
help string. IIRC you can specify which base revision a patch applies to (ie. it
may apply to an older revision, not necessarily to the current HEAD).
It has also quite some bitrot (git-* direct invocation, use of cg-tag, surely more).
^ permalink raw reply
* RE: Failure using webdav basic auth by git client
From: Pyeron, Jason J CTR (US) @ 2012-11-12 12:27 UTC (permalink / raw)
To: git@vger.kernel.org
In-Reply-To: <20121111182842.GC21654@sigill.intra.peff.net>
[-- Attachment #1: Type: text/plain, Size: 1001 bytes --]
> -----Original Message-----
> From: Jeff King
> Sent: Sunday, November 11, 2012 1:29 PM
>
> On Sun, Nov 11, 2012 at 01:09:02PM -0500, Jason Pyeron wrote:
>
> > > My google fu has failed me on this issue. I am trying to setup
> http(s)
> > > repositories for git. If I require authenticated users then git
> asks
> > > for a username and password for the first volley of communications,
> but
> > > then does not include the Authorization header on subsequent
> requests.
> > [...]
> > > > GET /git/test/info/refs?service=git-receive-pack HTTP/1.1
> > > User-Agent: git/1.7.9
>
> Can you try with a more recent git version? There were some bugs with
> on-demand http auth when using the dumb protocol (which I see you are
> using). They were fixed in v1.7.10.2 and higher.
Having some troubles compiling the maint branch on cygwin (same issue for master).
>
> Also, consider setting up the smart-http protocol, as it is way more
> efficient.
Will look into that after I get git compiling...
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5615 bytes --]
^ permalink raw reply
* Re: git merge commits are non-deterministic? what changed?
From: Michael J Gruber @ 2012-11-12 11:27 UTC (permalink / raw)
To: Ulrich Spörlein; +Cc: Jeff King, Matthieu Moy, Andreas Schwab, git
In-Reply-To: <20121109182753.GQ69724@acme.spoerlein.net>
Ulrich Spörlein venit, vidit, dixit 09.11.2012 19:27:
> On Fri, 2012-11-09 at 11:16:47 -0500, Jeff King wrote:
>> On Fri, Nov 09, 2012 at 04:52:48PM +0100, Matthieu Moy wrote:
>>
>>> Ulrich Spörlein <uqs@spoerlein.net> writes:
>>>
>>>>>> 2. Why the hell is the commit hash dependent on the ordering of the
>>>>>> parent commits? IMHO it should sort the set of parents before
>>>>>> calculating the hash ...
>>>>>
>>>>> What would be the sort key?
>>>>
>>>> Trivially, the hash of the parents itself. So you'd always get
>>>>
>>>> ...
>>>> parent 0000
>>>> parent 1111
>>>> parent aaaa
>>>> parent ffff
>>>
>>> That would change the behavior of --first-parent. Or you'd need to
>>> compute the sha1 of the sorted list, but keep the unsorted one in the
>>> commit. Possible, but weird ;-).
>>
>> Right. The reason that merge parents are stored in the order given on
>> the command line is not random or because it was not considered. It
>> encodes a valuable piece of information: did the user merge "foo" into
>> "bar", or did they merge "bar" into "foo"?
>>
>> So I think this discussion is going in the wrong direction; git should
>> never sort the parents, because the order is meaningful. The original
>> complaint was that a run of svn2git produced different results on two
>> different git versions. The important question to me is: did svn2git
>> feed the parents to git in the same order?
>>
>> If it did, and git produced different results, then that is a serious
>> bug.
>>
>> If it did not, then the issue needs to be resolved in svn2git (which
>> _may_ want to sort the parents that it feeds to git, but it would depend
>> on whether the order it is currently presenting is meaningful).
>
> Yeah, thanks, looks like I have some more work to do. I don't quite get
> how it could come up with a different order, seeing that it is using svn
> as the base.
>
> Will run some more experiments, thanks for the info so far.
There was a change in the order in which "git cherry-pick A B C" applies
the commits. It's the only odering affecting change in 1.8.0 that I can
think of right now.
Michael
^ permalink raw reply
* Re: [PATCH v5 11/15] remote-testgit: make clear the 'done' feature
From: Max Horn @ 2012-11-12 11:20 UTC (permalink / raw)
To: Felipe Contreras
Cc: git, Junio C Hamano, Johannes Schindelin, Jeff King,
Sverre Rabbelier, Brandon Casey, Brandon Casey, Jonathan Nieder,
Ilari Liusvaara, Pete Wyckoff, Ben Walton, Matthieu Moy,
Julian Phillips
In-Reply-To: <CAMP44s0o1eP+aeT0AHu4uP1NPLqJq56qUDb-+F_x5NjoJCnf+A@mail.gmail.com>
On 11.11.2012, at 22:22, Felipe Contreras wrote:
> On Sun, Nov 11, 2012 at 9:49 PM, Max Horn <max@quendi.de> wrote:
>>
>> On 11.11.2012, at 14:59, Felipe Contreras wrote:
>>
>>> People seeking for reference would find it useful.
>>
>> Hm, I don't understand this commit message. Probably means I am j git fast-export --use-done-featureust too dumb, but since I am one of those people who would likely be seeking for reference, I would really appreciate if it could clarified. Like, for example, I don't see how the patch below makes anything "clear", it just seems to change the "import" command of git-remote-testgit to make use of the 'done' feature?
>
> No, the done feature was there already, but not so visible: git
> fast-export --use-done-feature <-there. Which is the problem, it's too
> easy to miss, therefore the need to make it clear.
Aha, now I understand what this patch is about. So I would suggest this alternate commit message:
remote-testgit: make it explicit clear that we use the 'done' feature
Previously we relied on passing '--use-done-feature ' to git fast-export, which is
easy to miss when looking at this script. Since remote-testgit is also a reference
implementation, we now explicitly output 'feature done' / 'done' to make it
crystal clear that we implement this feature.
Or perhaps a little bit less verbose. With a commit message like the above, I think I would have grokked the patch right away. With the original message, that was not the case (else I wouldn't have wrote my initial email). And even though I now understand (or at least believe to understand) the patch, I don't think the original message is that helpful... indeed, "make clear the 'done' feature" is ambiguous. You meant it as "make clear the 'done' feature is implemented / used", while I understood it as "make clear what the 'done' feature is about". Looking at the patch can help to resolve that, but (a) my wrong interpretation threw me off-track and (b) I thought that the point of commit messages was to give an overview of a patch without having to look at it...
So at the very least, the message should explain what exactly is "made clear".
Anyway, a small change to the commit message hopefully will not be a problem. :-)
Cheers,
Max
^ permalink raw reply
* Re: [PATCH] Documentation/log: fix description of format.pretty
From: Ramkumar Ramachandra @ 2012-11-12 9:39 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Git List
In-Reply-To: <20121112080527.GB3581@elie.Belkin>
Hi Jonathan,
Jonathan Nieder wrote:
> Hi Ram,
>
> Ramkumar Ramachandra wrote:
>
>> 59893a88 (Documentation/log: add a CONFIGURATION section, 2010-05-08)
>> mentioned that `format.pretty` is the default for the `--format`
>> option. Such an option never existed,
>
> False. Have you tried it?
Oops, I read about `--pretty` in pretty-formats.txt and didn't realize
that `--format` existed. However, your patch is still wrong because
there seems to be a subtle (and confusing) difference between
`--pretty` and `--format`. In the latter, you can't omit the format,
and expect it to be picked up from format.pretty:
$ git log --format
fatal: unrecognized argument: --format
Instead, you have to specify the format explicitly:
$ git log --format=medium
So, we should change the commit message in my patch?
Ram
^ permalink raw reply
* Re: [PATCHv2] replace: parse revision argument for -d
From: Michael J Gruber @ 2012-11-12 8:51 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20121109164808.GE19725@sigill.intra.peff.net>
Jeff King venit, vidit, dixit 09.11.2012 17:48:
> On Mon, Oct 29, 2012 at 02:23:27PM +0100, Michael J Gruber wrote:
>
>> 'git replace' parses the revision arguments when it creates replacements
>> (so that a sha1 can be abbreviated, e.g.) but not when deleting
>> replacements.
>>
>> Make it parse the arguments to 'replace -d' in the same way.
>>
>> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
>> ---
>> v2 has the simplified error check as per Jeff, and a reworded message.
>> Comes with a free test case, too.
>
> I noticed this today in my pile of "to look at" patches. Sorry for being
> slow.
No problem. This is not urgent, and it takes some effort to look at code
amongst all those black-and-white discussions. [It even takes effort to
refrain from responding when you words are being twisted around...]
>> for (p = argv; *p; p++) {
>> - if (snprintf(ref, sizeof(ref), "refs/replace/%s", *p)
>> - >= sizeof(ref)) {
>> - error("replace ref name too long: %.*s...", 50, *p);
>> + q = *p;
>> + if (get_sha1(q, sha1)) {
>> + error("Failed to resolve '%s' as a valid ref.", q);
>> had_error = 1;
>> continue;
>> }
>
> Looks reasonable.
>
>> + q = sha1_to_hex(sha1);
>> + snprintf(ref, sizeof(ref), "refs/replace/%s", q);
>> if (read_ref(ref, sha1)) {
>> - error("replace ref '%s' not found.", *p);
>> + error("replace ref '%s' not found.", q);
>
> I worry a little about assuming that "q", which points to a static
> internal buffer of sha1_to_hex, is still valid after calling read_ref.
> We'll end up in resolve_ref, which might need to do considerable work
> (e.g., loading the whole packed refs file). Just grepping for
> sha1_to_hex, I don't think it is a problem currently, but it might be
> worth copying the value (you could even point into the "ref" buffer to
> avoid dealing with an extra allocation).
We could just leave '*p' as it is (after all, that was the user input),
or use 'ref+strlen("refs/replace/")'.
I wasn't aware of the volatile nature of the return value. Thanks for
spotting!
Michael
^ permalink raw reply
* "git imap-send" with HTML preformatting broken for multipart messages
From: Michael Haggerty @ 2012-11-12 8:43 UTC (permalink / raw)
To: git discussion list, Jeremy White, Mike McCormack
I just noticed that "git imap-send" with imap.preformattedHTML turned on
is broken for multipart messages. The problem is that "git imap-send"
embeds *everything* after the main email header in <pre></pre> and
HTML-escapes it, instead of splitting out the email parts and quoting
their bodies individually.
Ironically, the "git imap-send" manpage specifically lists the typical
usage as
git format-patch --signoff --stdout --attach origin | git imap-send
which is broken if imap.preformattedHTML is set.
It seems to me that rather than fix "git imap-send" (which would require
it to become more complicated), it would be better to teach "git
format-patch" how to do preformatting and restrict "git imap-send" to
sending messages verbatim to an IMAP server. Moving the functionality
to "git format-patch" would also make it possible to create preformatted
emails to be used with other transports.
Oh, and, by the way, "git imap-send" is utterly untested by the test
suite. The fact that it is intrinsically hard to test without lots of
extra infrastructure is another argument for making it as stupid as
possible.
I don't plan to work on this.
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* Re: [PATCH] Documentation/log: fix description of format.pretty
From: Jonathan Nieder @ 2012-11-12 8:05 UTC (permalink / raw)
To: Ramkumar Ramachandra; +Cc: Git List
In-Reply-To: <CALkWK0=hdmYF2VoOZY4F7+yPD8D0rBnPY-tvp5pryRWp-0WBeg@mail.gmail.com>
Hi Ram,
Ramkumar Ramachandra wrote:
> 59893a88 (Documentation/log: add a CONFIGURATION section, 2010-05-08)
> mentioned that `format.pretty` is the default for the `--format`
> option. Such an option never existed,
False. Have you tried it?
Thanks,
Jonathan
^ permalink raw reply
* Re: Bizarre problem cloning repo from Codeplex
From: Andreas Schwab @ 2012-11-12 7:44 UTC (permalink / raw)
To: Enrico Weigelt; +Cc: Jeremy Morton, git
In-Reply-To: <09766c5a-faa0-48dc-8c0a-6551cf3b5db9@zcs>
Enrico Weigelt <enrico.weigelt@vnc.biz> writes:
>> > Their webserver seems to be configured quite restrictively
>> > (eg. cannot access files like 'packed-refs').
>>
>> Probably it just doesn't exist.
>
> Aren' these files requied ?
No. If you've never run git pack-refs it's never created.
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* [PATCH v3 3/5] push: flag updates
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
In-Reply-To: <1352693288-7396-1-git-send-email-chris@rorvick.com>
If the reference exists on the remote and the the update is not a
delete, then mark as an update. This is in preparation for handling
tags and branches differently when pushing.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
---
cache.h | 1 +
remote.c | 18 +++++++++++-------
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/cache.h b/cache.h
index 4e25840..9712d1b 100644
--- a/cache.h
+++ b/cache.h
@@ -1003,6 +1003,7 @@ struct ref {
merge:1,
nonfastforward:1,
forwardable:1,
+ update:1,
deletion:1;
enum {
REF_STATUS_NONE = 0,
diff --git a/remote.c b/remote.c
index 5ecd58d..7fa9db6 100644
--- a/remote.c
+++ b/remote.c
@@ -1323,15 +1323,19 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
old->type == OBJ_COMMIT && new->type == OBJ_COMMIT);
}
- ref->nonfastforward =
+ ref->update =
!ref->deletion &&
- !is_null_sha1(ref->old_sha1) &&
- (!has_sha1_file(ref->old_sha1)
- || !ref_newer(ref->new_sha1, ref->old_sha1));
+ !is_null_sha1(ref->old_sha1);
- if (ref->nonfastforward && !ref->force && !force_update) {
- ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
- continue;
+ if (ref->update) {
+ ref->nonfastforward =
+ !has_sha1_file(ref->old_sha1)
+ || !ref_newer(ref->new_sha1, ref->old_sha1);
+
+ if (ref->nonfastforward && !ref->force && !force_update) {
+ ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
+ continue;
+ }
}
}
}
--
1.8.0
^ permalink raw reply related
* [PATCH v3 5/5] push: update remote tags only with force
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
In-Reply-To: <1352693288-7396-1-git-send-email-chris@rorvick.com>
References are allowed to update from one commit-ish to another if the
former is a ancestor of the latter. This behavior is oriented to
branches which are expected to move with commits. Tag references are
expected to be static in a repository, though, thus an update to a
tag (lightweight and annotated) should be rejected unless the update is
forced.
To enable this functionality, the following checks have been added to
set_ref_status_for_push() for updating refs (i.e, not new or deletion)
to restrict fast-forwarding in pushes:
1) The old and new references must be commits. If this fails,
it is not a valid update for a branch.
2) The reference name cannot start with "refs/tags/". This
catches lightweight tags which (usually) point to commits
and therefore would not be caught by (1).
If either of these checks fails, then it is flagged (by default) with a
status indicating the update is being rejected due to the reference
already existing in the remote. This can be overridden by passing
--force to git push.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
---
Documentation/git-push.txt | 10 +++++-----
builtin/push.c | 3 +--
builtin/send-pack.c | 5 +++++
cache.h | 1 +
remote.c | 8 +++++++-
send-pack.c | 1 +
t/t5516-fetch-push.sh | 30 +++++++++++++++++++++++++++++-
transport-helper.c | 6 ++++++
transport.c | 8 ++++++--
9 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index fe46c42..479e25f 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -51,11 +51,11 @@ be named. If `:`<dst> is omitted, the same ref as <src> will be
updated.
+
The object referenced by <src> is used to update the <dst> reference
-on the remote side, but by default this is only allowed if the
-update can fast-forward <dst>. By having the optional leading `+`,
-you can tell git to update the <dst> ref even when the update is not a
-fast-forward. This does *not* attempt to merge <src> into <dst>. See
-EXAMPLES below for details.
+on the remote side. By default this is only allowed if the update is
+a branch, and then only if it can fast-forward <dst>. By having the
+optional leading `+`, you can tell git to update the <dst> ref even when
+the update is not a branch or it is not a fast-forward. This does *not*
+attempt to merge <src> into <dst>. See EXAMPLES below for details.
+
`tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
+
diff --git a/builtin/push.c b/builtin/push.c
index 77340c0..d097348 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -222,8 +222,7 @@ static const char message_advice_checkout_pull_push[] =
static const char message_advice_ref_already_exists[] =
N_("Updates were rejected because a matching reference already exists in\n"
- "the remote and the update is not a fast-forward. Use git push -f if\n"
- "you really want to make this update.");
+ "the remote. Use git push -f if you really want to make this update.");
static void advise_pull_before_push(void)
{
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index fda28bc..1eabf42 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -44,6 +44,11 @@ static void print_helper_status(struct ref *ref)
msg = "non-fast forward";
break;
+ case REF_STATUS_REJECT_ALREADY_EXISTS:
+ res = "error";
+ msg = "already exists";
+ break;
+
case REF_STATUS_REJECT_NODELETE:
case REF_STATUS_REMOTE_REJECT:
res = "error";
diff --git a/cache.h b/cache.h
index e61dca3..127e504 100644
--- a/cache.h
+++ b/cache.h
@@ -1011,6 +1011,7 @@ struct ref {
REF_STATUS_NONE = 0,
REF_STATUS_OK,
REF_STATUS_REJECT_NONFASTFORWARD,
+ REF_STATUS_REJECT_ALREADY_EXISTS,
REF_STATUS_REJECT_NODELETE,
REF_STATUS_UPTODATE,
REF_STATUS_REMOTE_REJECT,
diff --git a/remote.c b/remote.c
index 82ba5ed..e5f8a56 100644
--- a/remote.c
+++ b/remote.c
@@ -1334,7 +1334,13 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
!has_sha1_file(ref->old_sha1)
|| !ref_newer(ref->new_sha1, ref->old_sha1);
- if (ref->nonfastforward) {
+ if (!ref->forwardable) {
+ ref->requires_force = 1;
+ if (!force_ref_update) {
+ ref->status = REF_STATUS_REJECT_ALREADY_EXISTS;
+ continue;
+ }
+ } else if (ref->nonfastforward) {
ref->requires_force = 1;
if (!force_ref_update) {
ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
diff --git a/send-pack.c b/send-pack.c
index f50dfd9..1c375f0 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -229,6 +229,7 @@ int send_pack(struct send_pack_args *args,
/* Check for statuses set by set_ref_status_for_push() */
switch (ref->status) {
case REF_STATUS_REJECT_NONFASTFORWARD:
+ case REF_STATUS_REJECT_ALREADY_EXISTS:
case REF_STATUS_UPTODATE:
continue;
default:
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b5417cc..afb9b1b 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -368,7 +368,7 @@ test_expect_success 'push with colon-less refspec (2)' '
git branch -D frotz
fi &&
git tag -f frotz &&
- git push testrepo frotz &&
+ git push -f testrepo frotz &&
check_push_result $the_commit tags/frotz &&
check_push_result $the_first_commit heads/frotz
@@ -929,6 +929,34 @@ test_expect_success 'push into aliased refs (inconsistent)' '
)
'
+test_expect_success 'push tag requires --force to update remote tag' '
+ mk_test heads/master &&
+ mk_child child1 &&
+ mk_child child2 &&
+ (
+ cd child1 &&
+ git tag lw_tag &&
+ git tag -a -m "message 1" ann_tag &&
+ git push ../child2 lw_tag &&
+ git push ../child2 ann_tag &&
+ >file1 &&
+ git add file1 &&
+ git commit -m "file1" &&
+ git tag -f lw_tag &&
+ git tag -f -a -m "message 2" ann_tag &&
+ test_must_fail git push ../child2 lw_tag &&
+ test_must_fail git push ../child2 ann_tag &&
+ git push --force ../child2 lw_tag &&
+ git push --force ../child2 ann_tag &&
+ git tag -f lw_tag HEAD~ &&
+ git tag -f -a -m "message 3" ann_tag &&
+ test_must_fail git push ../child2 lw_tag &&
+ test_must_fail git push ../child2 ann_tag &&
+ git push --force ../child2 lw_tag &&
+ git push --force ../child2 ann_tag
+ )
+'
+
test_expect_success 'push --porcelain' '
mk_empty &&
echo >.git/foo "To testrepo" &&
diff --git a/transport-helper.c b/transport-helper.c
index 4713b69..965b778 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -661,6 +661,11 @@ static void push_update_ref_status(struct strbuf *buf,
free(msg);
msg = NULL;
}
+ else if (!strcmp(msg, "already exists")) {
+ status = REF_STATUS_REJECT_ALREADY_EXISTS;
+ free(msg);
+ msg = NULL;
+ }
}
if (*ref)
@@ -720,6 +725,7 @@ static int push_refs_with_push(struct transport *transport,
/* Check for statuses set by set_ref_status_for_push() */
switch (ref->status) {
case REF_STATUS_REJECT_NONFASTFORWARD:
+ case REF_STATUS_REJECT_ALREADY_EXISTS:
case REF_STATUS_UPTODATE:
continue;
default:
diff --git a/transport.c b/transport.c
index 632f8b0..a380ad7 100644
--- a/transport.c
+++ b/transport.c
@@ -695,6 +695,10 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
"non-fast-forward", porcelain);
break;
+ case REF_STATUS_REJECT_ALREADY_EXISTS:
+ print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+ "already exists", porcelain);
+ break;
case REF_STATUS_REMOTE_REJECT:
print_ref_status('!', "[remote rejected]", ref,
ref->deletion ? NULL : ref->peer_ref,
@@ -740,12 +744,12 @@ void transport_print_push_status(const char *dest, struct ref *refs,
ref->status != REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
- if (!ref->forwardable)
- *reject_mask |= REJECT_ALREADY_EXISTS;
if (!strcmp(head, ref->name))
*reject_mask |= REJECT_NON_FF_HEAD;
else
*reject_mask |= REJECT_NON_FF_OTHER;
+ } else if (ref->status == REF_STATUS_REJECT_ALREADY_EXISTS) {
+ *reject_mask |= REJECT_ALREADY_EXISTS;
}
}
}
--
1.8.0
^ permalink raw reply related
* [PATCH v3 4/5] push: flag updates that require force
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
In-Reply-To: <1352693288-7396-1-git-send-email-chris@rorvick.com>
Add a flag for indicating an update to a reference requires force.
Currently the nonfastforward flag of a ref is used for this when
generating status the status message. A separate flag insulates the
status logic from the details of set_ref_status_for_push().
Signed-off-by: Chris Rorvick <chris@rorvick.com>
---
cache.h | 4 +++-
remote.c | 11 ++++++++---
transport.c | 2 +-
3 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/cache.h b/cache.h
index 9712d1b..e61dca3 100644
--- a/cache.h
+++ b/cache.h
@@ -999,7 +999,9 @@ struct ref {
unsigned char old_sha1[20];
unsigned char new_sha1[20];
char *symref;
- unsigned int force:1,
+ unsigned int
+ force:1,
+ requires_force:1,
merge:1,
nonfastforward:1,
forwardable:1,
diff --git a/remote.c b/remote.c
index 7fa9db6..82ba5ed 100644
--- a/remote.c
+++ b/remote.c
@@ -1285,6 +1285,8 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
struct ref *ref;
for (ref = remote_refs; ref; ref = ref->next) {
+ int force_ref_update = ref->force || force_update;
+
if (ref->peer_ref)
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
else if (!send_mirror)
@@ -1332,9 +1334,12 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
!has_sha1_file(ref->old_sha1)
|| !ref_newer(ref->new_sha1, ref->old_sha1);
- if (ref->nonfastforward && !ref->force && !force_update) {
- ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
- continue;
+ if (ref->nonfastforward) {
+ ref->requires_force = 1;
+ if (!force_ref_update) {
+ ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
+ continue;
+ }
}
}
}
diff --git a/transport.c b/transport.c
index 1657798..632f8b0 100644
--- a/transport.c
+++ b/transport.c
@@ -659,7 +659,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain)
const char *msg;
strcpy(quickref, status_abbrev(ref->old_sha1));
- if (ref->nonfastforward) {
+ if (ref->requires_force) {
strcat(quickref, "...");
type = '+';
msg = "forced update";
--
1.8.0
^ permalink raw reply related
* [PATCH v3 2/5] push: add advice for rejected tag reference
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
In-Reply-To: <1352693288-7396-1-git-send-email-chris@rorvick.com>
Advising the user to fetch and merge only makes sense if the rejected
reference is a branch. If none of the rejections were for branches,
tell the user they need to force the update(s).
Signed-off-by: Chris Rorvick <chris@rorvick.com>
---
builtin/push.c | 16 ++++++++++++++--
cache.h | 1 +
remote.c | 7 +++++++
transport.c | 6 ++++--
transport.h | 5 +++--
5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/builtin/push.c b/builtin/push.c
index eaeaf7e..77340c0 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -220,6 +220,11 @@ static const char message_advice_checkout_pull_push[] =
"(e.g. 'git pull') before pushing again.\n"
"See the 'Note about fast-forwards' in 'git push --help' for details.");
+static const char message_advice_ref_already_exists[] =
+ N_("Updates were rejected because a matching reference already exists in\n"
+ "the remote and the update is not a fast-forward. Use git push -f if\n"
+ "you really want to make this update.");
+
static void advise_pull_before_push(void)
{
if (!advice_push_non_ff_current || !advice_push_nonfastforward)
@@ -241,6 +246,11 @@ static void advise_checkout_pull_push(void)
advise(_(message_advice_checkout_pull_push));
}
+static void advise_ref_already_exists(void)
+{
+ advise(_(message_advice_ref_already_exists));
+}
+
static int push_with_options(struct transport *transport, int flags)
{
int err;
@@ -265,13 +275,15 @@ static int push_with_options(struct transport *transport, int flags)
if (!err)
return 0;
- if (reject_mask & NON_FF_HEAD) {
+ if (reject_mask & REJECT_NON_FF_HEAD) {
advise_pull_before_push();
- } else if (reject_mask & NON_FF_OTHER) {
+ } else if (reject_mask & REJECT_NON_FF_OTHER) {
if (default_matching_used)
advise_use_upstream();
else
advise_checkout_pull_push();
+ } else if (reject_mask & REJECT_ALREADY_EXISTS) {
+ advise_ref_already_exists();
}
return 1;
diff --git a/cache.h b/cache.h
index dbd8018..4e25840 100644
--- a/cache.h
+++ b/cache.h
@@ -1002,6 +1002,7 @@ struct ref {
unsigned int force:1,
merge:1,
nonfastforward:1,
+ forwardable:1,
deletion:1;
enum {
REF_STATUS_NONE = 0,
diff --git a/remote.c b/remote.c
index 04fd9ea..5ecd58d 100644
--- a/remote.c
+++ b/remote.c
@@ -1316,6 +1316,13 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
* always allowed.
*/
+ if (prefixcmp(ref->name, "refs/tags/")) {
+ struct object *old = parse_object(ref->old_sha1);
+ struct object *new = parse_object(ref->new_sha1);
+ ref->forwardable = (old && new &&
+ old->type == OBJ_COMMIT && new->type == OBJ_COMMIT);
+ }
+
ref->nonfastforward =
!ref->deletion &&
!is_null_sha1(ref->old_sha1) &&
diff --git a/transport.c b/transport.c
index ae9fda8..1657798 100644
--- a/transport.c
+++ b/transport.c
@@ -740,10 +740,12 @@ void transport_print_push_status(const char *dest, struct ref *refs,
ref->status != REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
+ if (!ref->forwardable)
+ *reject_mask |= REJECT_ALREADY_EXISTS;
if (!strcmp(head, ref->name))
- *reject_mask |= NON_FF_HEAD;
+ *reject_mask |= REJECT_NON_FF_HEAD;
else
- *reject_mask |= NON_FF_OTHER;
+ *reject_mask |= REJECT_NON_FF_OTHER;
}
}
}
diff --git a/transport.h b/transport.h
index 1f9699c..7e86352 100644
--- a/transport.h
+++ b/transport.h
@@ -140,8 +140,9 @@ int transport_set_option(struct transport *transport, const char *name,
void transport_set_verbosity(struct transport *transport, int verbosity,
int force_progress);
-#define NON_FF_HEAD 0x01
-#define NON_FF_OTHER 0x02
+#define REJECT_NON_FF_HEAD 0x01
+#define REJECT_NON_FF_OTHER 0x02
+#define REJECT_ALREADY_EXISTS 0x04
int transport_push(struct transport *connection,
int refspec_nr, const char **refspec, int flags,
--
1.8.0
^ permalink raw reply related
* [PATCH v3 1/5] push: return reject reasons via a mask
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
In-Reply-To: <1352693288-7396-1-git-send-email-chris@rorvick.com>
Pass all rejection reasons back from transport_push(). The logic is
simpler and more flexible with regard to providing useful feedback.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
---
builtin/push.c | 13 ++++---------
builtin/send-pack.c | 4 ++--
transport.c | 17 ++++++++---------
transport.h | 9 +++++----
4 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/builtin/push.c b/builtin/push.c
index db9ba30..eaeaf7e 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -244,7 +244,7 @@ static void advise_checkout_pull_push(void)
static int push_with_options(struct transport *transport, int flags)
{
int err;
- int nonfastforward;
+ unsigned int reject_mask;
transport_set_verbosity(transport, verbosity, progress);
@@ -257,7 +257,7 @@ static int push_with_options(struct transport *transport, int flags)
if (verbosity > 0)
fprintf(stderr, _("Pushing to %s\n"), transport->url);
err = transport_push(transport, refspec_nr, refspec, flags,
- &nonfastforward);
+ &reject_mask);
if (err != 0)
error(_("failed to push some refs to '%s'"), transport->url);
@@ -265,18 +265,13 @@ static int push_with_options(struct transport *transport, int flags)
if (!err)
return 0;
- switch (nonfastforward) {
- default:
- break;
- case NON_FF_HEAD:
+ if (reject_mask & NON_FF_HEAD) {
advise_pull_before_push();
- break;
- case NON_FF_OTHER:
+ } else if (reject_mask & NON_FF_OTHER) {
if (default_matching_used)
advise_use_upstream();
else
advise_checkout_pull_push();
- break;
}
return 1;
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index d342013..fda28bc 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -85,7 +85,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
int send_all = 0;
const char *receivepack = "git-receive-pack";
int flags;
- int nonfastforward = 0;
+ unsigned int reject_mask;
int progress = -1;
argv++;
@@ -223,7 +223,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
ret |= finish_connect(conn);
if (!helper_status)
- transport_print_push_status(dest, remote_refs, args.verbose, 0, &nonfastforward);
+ transport_print_push_status(dest, remote_refs, args.verbose, 0, &reject_mask);
if (!args.dry_run && remote) {
struct ref *ref;
diff --git a/transport.c b/transport.c
index 9932f40..ae9fda8 100644
--- a/transport.c
+++ b/transport.c
@@ -714,7 +714,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
}
void transport_print_push_status(const char *dest, struct ref *refs,
- int verbose, int porcelain, int *nonfastforward)
+ int verbose, int porcelain, unsigned int *reject_mask)
{
struct ref *ref;
int n = 0;
@@ -733,18 +733,17 @@ void transport_print_push_status(const char *dest, struct ref *refs,
if (ref->status == REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
- *nonfastforward = 0;
+ *reject_mask = 0;
for (ref = refs; ref; ref = ref->next) {
if (ref->status != REF_STATUS_NONE &&
ref->status != REF_STATUS_UPTODATE &&
ref->status != REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
- if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD &&
- *nonfastforward != NON_FF_HEAD) {
+ if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
if (!strcmp(head, ref->name))
- *nonfastforward = NON_FF_HEAD;
+ *reject_mask |= NON_FF_HEAD;
else
- *nonfastforward = NON_FF_OTHER;
+ *reject_mask |= NON_FF_OTHER;
}
}
}
@@ -1031,9 +1030,9 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing)
int transport_push(struct transport *transport,
int refspec_nr, const char **refspec, int flags,
- int *nonfastforward)
+ unsigned int *reject_mask)
{
- *nonfastforward = 0;
+ *reject_mask = 0;
transport_verify_remote_names(refspec_nr, refspec);
if (transport->push) {
@@ -1099,7 +1098,7 @@ int transport_push(struct transport *transport,
if (!quiet || err)
transport_print_push_status(transport->url, remote_refs,
verbose | porcelain, porcelain,
- nonfastforward);
+ reject_mask);
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
set_upstreams(transport, remote_refs, pretend);
diff --git a/transport.h b/transport.h
index 4a61c0c..1f9699c 100644
--- a/transport.h
+++ b/transport.h
@@ -140,11 +140,12 @@ int transport_set_option(struct transport *transport, const char *name,
void transport_set_verbosity(struct transport *transport, int verbosity,
int force_progress);
-#define NON_FF_HEAD 1
-#define NON_FF_OTHER 2
+#define NON_FF_HEAD 0x01
+#define NON_FF_OTHER 0x02
+
int transport_push(struct transport *connection,
int refspec_nr, const char **refspec, int flags,
- int * nonfastforward);
+ unsigned int * reject_mask);
const struct ref *transport_get_remote_refs(struct transport *transport);
@@ -170,7 +171,7 @@ void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int v
int transport_refs_pushed(struct ref *ref);
void transport_print_push_status(const char *dest, struct ref *refs,
- int verbose, int porcelain, int *nonfastforward);
+ int verbose, int porcelain, unsigned int *reject_mask);
typedef void alternate_ref_fn(const struct ref *, void *);
extern void for_each_alternate_ref(alternate_ref_fn, void *);
--
1.8.0
^ permalink raw reply related
* [PATCH v3 0/5] push: update remote tags only with force
From: Chris Rorvick @ 2012-11-12 4:08 UTC (permalink / raw)
To: git
Cc: Chris Rorvick, Angelo Borsotti, Drew Northup, Michael Haggerty,
Philip Oakley, Johannes Sixt, Kacper Kornet, Jeff King,
Felipe Contreras
Minor changes since from v2 set. Reposting primarily because I mucked
up the Cc: list (again) and hoping to route feedback to the appropriate
audience.
This patch set can be divided into two sets:
1. Provide useful advice for rejected tag references.
push: return reject reasons via a mask
push: add advice for rejected tag reference
Recommending a merge to resolve a rejected tag update seems
nonsensical since the tag does not come along for the ride. These
patches change the advice for rejected tags to suggest using
"push -f".
2. Require force when updating tag references, even on a fast-forward.
push: flag updates
push: flag updates that require force
push: update remote tags only with force
An email thread initiated by Angelo Borsotti did not come to a
consensus on how push should behave with regard to tag references.
I think a key point is that you currently cannot be sure your push
will not clobber a tag (lightweight or not) in the remote. Also, I
wonder what workflow would rely on this fast-forward feature of
pushed tag references that would not be better served a branch?
This patch set contains some minor updates from the previous set:
* remote.c: remove redundant check of ref->update
* transport.c: remove extraneous tab in indent
* builtin/send-pack.c: fix call to transport_print_push_status() (per
feedback from Peff)
Also, rebased against the latest master in git://github.com/peff/git.git
to pickup changes in nd/builtin-to-libgit.
Chris Rorvick (5):
push: return reject reasons via a mask
push: add advice for rejected tag reference
push: flag updates
push: flag updates that require force
push: update remote tags only with force
Documentation/git-push.txt | 10 +++++-----
builtin/push.c | 24 +++++++++++++++---------
builtin/send-pack.c | 9 +++++++--
cache.h | 7 ++++++-
remote.c | 38 ++++++++++++++++++++++++++++++--------
send-pack.c | 1 +
t/t5516-fetch-push.sh | 30 +++++++++++++++++++++++++++++-
transport-helper.c | 6 ++++++
transport.c | 25 +++++++++++++++----------
transport.h | 10 ++++++----
10 files changed, 120 insertions(+), 40 deletions(-)
--
1.8.0
^ permalink raw reply
* Re: Thanking the interim maintainer
From: Jeff King @ 2012-11-12 3:49 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlie7ldk5.fsf@alter.siamese.dyndns.org>
On Sun, Nov 11, 2012 at 07:12:26PM -0800, Junio C Hamano wrote:
> I am physically back but still am far from catching up with the list
> traffic (yet). After skimming my inbox, it appears that you have
> done a magnificent job keeping track of topics in flight and merging
> low-risk fixes early to the 'master' branch.
Thanks. I have a new-found appreciation of how much work goes into being
the maintainer.
> I am hoping that I can ask you to do another issue of "What's
> cooking" (or two) while I catch up with the traffic, to collect all
> worthy patches that are already published on the list ;-). After
> that, let us arrange for me to pick up the tips of topic branches
> you have and take it over (just telling me to run "log --oneline
> master..pu" might be sufficient if there is no "tentatively ejected"
> topic).
That sounds like a plan. I'll shoot for sending out a "What's Cooking"
Monday evening. I'll be traveling the rest of the week, so hopefully you
will be ready to pick things up by Tuesday.
-Peff
^ permalink raw reply
* Thanking the interim maintainer
From: Junio C Hamano @ 2012-11-12 3:12 UTC (permalink / raw)
To: peff; +Cc: git
I am physically back but still am far from catching up with the list
traffic (yet). After skimming my inbox, it appears that you have
done a magnificent job keeping track of topics in flight and merging
low-risk fixes early to the 'master' branch.
I am hoping that I can ask you to do another issue of "What's
cooking" (or two) while I catch up with the traffic, to collect all
worthy patches that are already published on the list ;-). After
that, let us arrange for me to pick up the tips of topic branches
you have and take it over (just telling me to run "log --oneline
master..pu" might be sufficient if there is no "tentatively ejected"
topic).
Thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox