* Re: Continue git clone after interruption
From: Nicolas Pitre @ 2009-08-22 8:13 UTC (permalink / raw)
To: Sam Vilain
Cc: Jakub Narebski, Tomasz Kontusz, git, Johannes Schindelin,
Scott Chacon
In-Reply-To: <1250920259.3644.11.camel@maia.lan>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 5187 bytes --]
On Sat, 22 Aug 2009, Sam Vilain wrote:
> On Fri, 2009-08-21 at 23:37 -0400, Nicolas Pitre wrote:
> > > What did you think about the bundle slicing stuff?
> >
> > If I didn't comment on it already, then I probably missed it and have no
> > idea.
>
> I really tire of repeating myself for your sole benefit. Please show
> some consideration for other people in the conversation by trying to
> listen. Thank-you.
I'm sorry but I have way too many emails to consider reading. This is
like ethernet: not a reliable transport, and lost packets means you have
to retransmit. Cut and paste does wonders, or even a link to previous
post.
> > > I think the first step here would be to allow thin pack generation to
> > > accept a bounded range of commits, any of the objects within which may
> > > be used as delta base candidates. That way, these "top down" thin packs
> > > can be generated. Currently of course it just uses the --not and makes
> > > "bottom up" thin packs.
> >
> > The pack is still almost top-down. It's only the missing delta base
> > that are in the other direction, refering to objects you have locally
> > and therefore older.
>
> Ok, but right now there's no way to specify that you want a thin pack,
> where the allowable base objects are *newer* than the commit range you
> wish to include.
Sure you can. Try this:
( echo "-$(git rev-parse v1.6.4)"; \
git rev-list --objects v1.6.2..v1.6.3 ) | \
git pack-objects --progress --stdout > foo.pack
That'll give you a thin pack for the _new_ objects that _appeared_
between v1.6.2 and v1.6.3, but which external delta base objects are
found in v1.6.4.
If you want _all_ the objects that are referenced from commits between
v1.6.2 and v1.6.3 then you just have to list them all for v1.6.2 in
addition to the rest:
( echo "-$(git rev-parse v1.6.4)"; \
git rev-list --objects v1.6.2..v1.6.3; \
git ls-tree -t -r v1.6.2 | cut -d' ' -f 3- | tr "\t" " "; ) | \
git pack-objects --progress --stdout > foo.pack
> What I said in my other e-mail where I showed how well it works taking
> a given bundle, and slicing it into a series of thin packs, was that it
> seems to add a bit of extra size to the resultant packs - best I got for
> slicing up the entire git.git run was about 20%. If this can be
> reduced to under 10% (say), then sending bundle slices would be quite
> reasonable by default for the benefit of making large fetches
> restartable, or even spreadable across multiple mirrors.
In theory you could have about no overhead. That all depends how you
slice the pack. If you want a pack to contain a fixed number of commits
(such that all objects introduced by a given commit are all in the same
pack) then you are of course putting a constraint on the possible delta
matches and compression result might be suboptimal. In comparison, with
a single big pack a given blob can delta against a blob from a
completely distant commit in the history graph if that provides a better
compression ratio.
If you slice your pack according to a size treshold, then you might
consider the --max-pack-size= argument to pack-objects. This currently
doesn't produce thin pack as delta objects whose base are stored in a
different pack than their base because of a pack split are simply not
stored as delta. Only a few line of code would need to be modified in
order to store those deltas nevertheless and turn those packs into thin
packs, preserving the optimal delta match. Of course cross pack delta
reference have to be REF_DELTA objects with headers about 16 to 17 bytes
larger than those of OFS_DELTA objects, so you will still have some
overhead.
> The object sorting stuff is something of a distraction; it's required
> for download spreading but not for the case at hand now.
Well, the idea of spreading small packs has its drawbacks. You still
might need to get a sizeable portion of them to get at least one usable
commit. And ideally you want the top commit in priority, which pretty
much impose an ordering on the packs you're likely to want first, unlike
with BitTorrent where you don't care as you normally want all
the blocks anyway.
If the goal is to make for faster downloads, then you could simply make
a bundle, copy it on multiple server, and slice your download across
those servers. This has the disadvantage of being static data that
doubles the disk (and cache) usage. That doesn't work too well with
shallow clones though.
If you were envisioning _clients_ à la BitTorrent putting up pack slices
instead, then in that case the slices have to be well defined entities,
like packs containing objects for known range of commits, but then we're
back to the delta inefficiency I mentioned above. And again this might
work only if a lot of people are interested in the same repository at
the same time, and of course most people have no big insentive to "seed"
once they got their copy. So I'm not sure if that might work that well
in practice.
This certainly still looks like a pretty cool project. But it is not
all the cool stuff that works well in real conditions I'm afraid. Just
my opinion of course.
Nicolas
^ permalink raw reply
* Re: [PATCH 2/2 (v3)] reset: make the output more user-friendly.
From: Matthieu Moy @ 2009-08-22 7:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3a7k767j.fsf@alter.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> writes:
> Thanks. Will queue.
Thanks,
> However, I'd change the justification.
Fine with me.
> The output from reset in question is merely an informative side effect, as
> opposed to what you actively ask "git diff" to give as its primary output.
> As such, your "consistency" argument is pretty weak. There is no reason
> to expect that the informative message to resemble one particular format
> (namely, --name-status) and not another (e.g. --stat or --name-only),
I agree that chosing --name-status over, like, --stat is rather
arbitrary. But Git has IMHO far too many languages for talking about
changes (--stat, --name-status, 'git status' itself, the 'git ls-files
-t' that I just discovered, and this 'bla: locally modified').
Reducing the number of formats by one is a good thing to me.
> Informative output from "git checkout $branch" when there are local
> changes is a much better precedent to refer to.
Yes.
> I am somewhat inclined to suggest that we should drop the new "Unstaged
> changes after ..." message, though.
I've thought about this too. The new format already looks much less
like an error message, which was really the problem I was solving. But
one advantage of the message contains two relevant informations:
"unstaged" and "after".
Intuitively, I would have thought that "git reset" was reporting what
it was doing, as it was doing it. So to me (before experimenting a bit
more and looking at the source code),
M foo.txt
M bar.txt
would mean "I've just reseted foo.txt and bar.txt, which were locally
modified", while actually "git reset" can very well show this message
after reseting only foo.txt, just informing the user that bar.txt is
also modified. So, at least to me, the semantics was very unclear, and
while I would have understood immediately with the one-liner message.
In short: no strong objection to remove this message, but to me it is
usefull.
--
Matthieu
^ permalink raw reply
* [ANNOUNCE] GIT 1.6.4.1
From: Junio C Hamano @ 2009-08-22 7:44 UTC (permalink / raw)
To: git
The latest maintenance release GIT 1.6.4.1 is available at the
usual places:
http://www.kernel.org/pub/software/scm/git/
git-1.6.4.1.tar.{gz,bz2} (source tarball)
git-htmldocs-1.6.4.1.tar.{gz,bz2} (preformatted docs)
git-manpages-1.6.4.1.tar.{gz,bz2} (preformatted docs)
The RPM binary packages for a few architectures are found in:
RPMS/$arch/git-*-1.6.4.1-1.fc9.$arch.rpm (RPM)
GIT v1.6.4.1 Release Notes
==========================
Fixes since v1.6.4
------------------
* An unquoted value in the configuration file, when it contains more than
one whitespaces in a row, got them replaced with a single space.
* "git am" used to accept a single piece of e-mail per file (not a mbox)
as its input, but multiple input format support in v1.6.4 broke it.
Apparently many people have been depending on this feature.
* The short help text for "git filter-branch" command was a single long
line, wrapped by terminals, and was hard to read.
* The "recursive" strategy of "git merge" segfaulted when a merge has
more than one merge-bases, and merging of these merge-bases involves
a rename/rename or a rename/add conflict.
* "git pull --rebase" did not use the right fork point when the
repository has already fetched from the upstream that rewinds the
branch it is based on in an earlier fetch.
* Explain the concept of fast-forward more fully in "git push"
documentation, and hint to refer to it from an error message when the
command refuses an update to protect the user.
* The default value for pack.deltacachesize, used by "git repack", is now
256M, instead of unbounded. Otherwise a repack of a moderately sized
repository would needlessly eat into swap.
* Document how "git repack" (hence "git gc") interacts with a repository
that borrows its objects from other repositories (e.g. ones created by
"git clone -s").
* "git show" on an annotated tag lacked a delimiting blank line between
the tag itself and the contents of the object it tags.
* "git verify-pack -v" erroneously reported number of objects with too
deep delta depths as "chain length 0" objects.
* Long names of authors and committers outside US-ASCII were sometimes
incorrectly shown in "gitweb".
Other minor documentation updates are included.
----------------------------------------------------------------
Changes since v1.6.4 are as follows:
Björn Steinbrink (1):
config: Keep inner whitespace verbatim
Erik Faye-Lund (1):
send-email: remove debug trace
Jakub Narebski (1):
gitweb/README: Document $base_url
Jeff King (3):
show: suppress extra newline when showing annotated tag
show: add space between multiple items
docs: describe impact of repack on "clone -s"
Jens Lehmann (1):
Documentation: git submodule: add missing options to synopsis
Johan Herland (1):
help.c: give correct structure's size to memset()
Johannes Schindelin (1):
filter-branch: add an example how to add ACKs to a range of commits
Junio C Hamano (5):
merge-recursive: don't segfault while handling rename clashes
t5510: harden the way verify-pack is used
verify-pack -v: do not report "chain length 0"
am: allow individual e-mail files as input
GIT 1.6.4.1
Mark A Rada (1):
git-instaweb: fix mod_perl detection for apache2
Matthieu Moy (3):
Better usage string for reflog.
push: point to 'git pull' and 'git push --force' in case of non-fast forward
filter-branch: make the usage string fit on 80 chars terminals.
Miklos Vajna (1):
hg-to-git: don't import the unused popen2 module
Nicolas Pitre (1):
don't let the delta cache grow unbounded in 'git repack'
Nicolas Sebrecht (1):
git-am: print fair error message when format detection fails
Ori Avtalion (1):
Change mentions of "git programs" to "git commands"
Paul Bolle (2):
Documentation: merge: one <remote> is required
Documentation: add: <filepattern>... is optional
Santi Béjar (2):
t5520-pull: Test for rebased upstream + fetch + pull --rebase
pull: support rebased upstream + fetch + pull --rebase
Zoltán Füzesi (1):
gitweb: parse_commit_text encoding fix
Štěpán Němec (1):
Fix typos in git-remote.txt and git-symbolic-ref.txt
^ permalink raw reply
* Re: [PATCH v3 1/9] sequencer: add "do_fast_forward()" to perform a fast forward
From: Junio C Hamano @ 2009-08-22 7:29 UTC (permalink / raw)
To: Christian Couder
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041616.4261.40442.chriscool@tuxfamily.org>
Christian Couder <chriscool@tuxfamily.org> writes:
> From: Stephan Beyer <s-beyer@gmx.net>
>
> This code is taken from the sequencer GSoC project:
>
> git://repo.or.cz/git/sbeyer.git
>
> (commit e7b8dab0c2a73ade92017a52bb1405ea1534ef20)
>
> but the messages have been changed to be the same as those
> displayed by git-rebase--interactive.sh.
Hmm, forgot to amend, or perhaps you sent out a wrong series?
The log message does not explain:
- why the patch adds a new static function that nobody calls;
- what the new function is good for;
which are the most important things in order to defend the change.
"The messages have been changed to..." hints that the original commit by
Stephan had different messages produced, perhaps so that it can be used in
a different context. I hoped, in an ideal world, perhaps Stephan defended
why the change was relevant to his project in some way, and because you
are using it in a different context that needs modification of the
message, perhaps Stephan's defense of his commit could be reworded to
defend your change here.
So I decided to take a look at the quoted commit to see if I can reword
this mess.
But the quoted commit e7b8dab0c2a73ade92017a52bb1405ea1534ef20 does not
even seem to be a commit that corresponds to this change. It is a merge
from upstream.
commit e7b8dab0c2a73ade92017a52bb1405ea1534ef20
Merge: 0c73ae7 99ddd24
Author: Stephan Beyer <s-beyer@gmx.net>
Date: Wed May 20 10:54:37 2009 +0200
Merge branch 'junio/master' into seq-builtin-dev
After this merge f79d4c8 "teach git-am to apply a patch to an unborn
branch" has to be reimplemented in sequencer by allowing the "patch"
insn on unborn branches.
The related test in t/t4150-am.sh is set to test_expect_failure.
Conflicts:
git-am.sh
It does not help that the function that is crucial to the implemention of
this new function, reset_almost_hard(), is not explained at all in the
earlier commit in the previous series (36f692b (sequencer: add
"reset_almost_hard()" and related functions, 2009-08-05).
The log message to the commit does not even hint in what sense "almost"
the function is, iow, in what situation it behaves exactly like "reset
--hard", and in what other situation it doesn't, and more importantly why
that distinction is there. I thought I asked these questions when the
previous series was submitted, but I do not remember ever seeing
satisfactory answers to them.
I am afraid that the whole cc/sequencer-rebase-i series needs a serious
reroll before it gets near 'next'.
Before giving up, I'll quickly re-review how (un)readable the log of each
commit is in the series. The following comments are mostly about the log
messages, which are supposed to entice people to review the code, and more
importantly, used as part of the release notes to summarize what the newly
added toys are about. If they are horrible, the code has little chance to
be even read, and I'll have a hard time merging the series up into a new
release.
6db6551 sequencer: add "builtin-sequencer--helper.c"
Good.
b512803 sequencer: add "make_patch" function to save a patch
Passably okay, but the limitation that it always writes into a file with a
fixed name "$SEQ_DIR/patch" should be noted in the log.
0ccc92b sequencer: free memory used in "make_patch" function
Should be squashed to the previous.
f121b06 rebase -i: use "git sequencer--helper --make-patch"
Good.
36f692b sequencer: add "reset_almost_hard()" and related functions
Horrible. See above.
9d41fbd sequencer: add comments about reset_almost_hard()
Should be squashed to the previous---lift some text to justify the
existence of the function in the commit log message. Even though
allow_dirty is referred to in the comment as affecting the behaviour, it
is unclear who sets that global variable using what interface, making the
reader suspect that maybe it should be a function parameter instead of a
global (but the other parts of the helper may also look at allow_dirty
and the internal implementation might be--I am just guessing--simpler this
way, in which case _that_ should be explained and justified).
022a9e7 sequencer: add "--reset-hard" option to "git sequencer--helper"
This by itself is Okay, provided if 36f692b were made readable. Then you
can expect the reader to know why reset_almost_hard() needs to be there,
and you need an interface to that function. Until then, it is totally
unclear why you need this, instead of using "reset --hard" itself.
ad28459 rebase -i: use "git sequencer--helper --reset-hard"
Ditto.
e4b3f0f sequencer: add "do_fast_forward()" to perform a fast forward
See above.
1d88073 sequencer: add "--fast-forward" option to "git sequencer--helper"
Okay.
6eff656 sequencer: let "git sequencer--helper" callers set "allow_dirty"
Why? What for?
877ddc1 rebase -i: use "git sequencer--helper --fast-forward"
It is unclear how this relates to the previous one, nor why it is more
appropriate than "reset-hard" it replaces.
ff312f0 revert: libify pick
Almost good.
ab67716 pick: libify "pick_help_msg()"
Good.
d871b0e sequencer: add "do_commit()" and related functions
We can see from "git show" what static functions that are never called in
this commit are added, but nobody explains why they are needed. For
example, do_commit() may create a new commit object, but does not share
the code with what "git commit" and/or "git commit-tree" do? If so, how?
If not, why not?
ac5fc4d sequencer: add "--cherry-pick" option to "git sequencer--helper"
Passably okay. I can see ff312f0 made about a half of cherry-pick
accessible to the sequencer, and this patch uses it to finish the other
half, although that is not explained in the log message. Also it is
unclear why the resulting "libified" code does not share more
infrastructure with "git cherry-pick" itself (and "git revert").
664c7ab rebase -i: use "git sequencer--helper --cherry-pick"
Passably okay, even though it is not quite convincing why using
sequencer-helper's cherry-pick option makes it easier to later port the
script, than keeping calls to cherry-pick.
^ permalink raw reply
* Re: How to recover from "reset --hard"
From: Ping Yin @ 2009-08-22 6:06 UTC (permalink / raw)
To: git mailing list
In-Reply-To: <46dff0320908211953u2f63cdb4m9cab863266a03df7@mail.gmail.com>
On Sat, Aug 22, 2009 at 10:53 AM, Ping Yin<pkufranky@gmail.com> wrote:
> After adding a file to index, i do a "reset --hard", then how do i
> recovery the file?
>
> I want write all lost files to a directory and find it according to
> the file size.
>
> Does "git fsck --lost-found" write this file to .git\lost-found\other ?
It does. I just remembered the wrong size of the file. Sorry for the noise.
^ permalink raw reply
* git fetch --depth=* broken?
From: Nicolas Pitre @ 2009-08-22 5:52 UTC (permalink / raw)
To: Junio C Hamano, Johannes Schindelin; +Cc: git
try out:
git clone --depth=1 git://git.kernel.org/pub/scm/git/git
cd git
git fetch --depth=2
It then silently fails, except for the return code of 1.
With -v this is the same result. Only if I remove --depth= do I get:
>From git://git.kernel.org/pub/scm/git/git
= [up to date] html -> origin/html
= [up to date] maint -> origin/maint
= [up to date] man -> origin/man
= [up to date] master -> origin/master
= [up to date] next -> origin/next
= [up to date] pu -> origin/pu
= [up to date] todo -> origin/todo
and a return code of 0.
It seems that commit c6bc400585 is partly responsible for that
misbehavior. At least reverting it makes the status list appear again
even with the presence of --depth=.
But still, actual result isn't any better. Using --depth=2 or
--depth=1000 doesn't change anything, unless there is _also_ a ref that
was updated on the remote end. Looks like the code is happy to conclude
that there is nothing to do if local refs match remote refs and never go
to talk further to the remote end ("no "shallow ..." nor "deepen ..."
are sent over the wire) despite the fact that --depth=1000 would
certainly have to trigger a pack transfer.
I'm also surprised that such thing as simple deepening of a repo is not
in the test suite. We certainly document this operation in the
git-fetch man page though.
The code in builtin-fetch-pack.c still looks rather confusing to me, so
hopefully you are more familiar with it and can provide a fix.
Nicolas
^ permalink raw reply
* Re: Continue git clone after interruption
From: Sam Vilain @ 2009-08-22 5:50 UTC (permalink / raw)
To: Nicolas Pitre
Cc: Jakub Narebski, Tomasz Kontusz, git, Johannes Schindelin,
Scott Chacon
In-Reply-To: <alpine.LFD.2.00.0908212324130.6044@xanadu.home>
On Fri, 2009-08-21 at 23:37 -0400, Nicolas Pitre wrote:
> What did you think about the bundle slicing stuff?
>
> If I didn't comment on it already, then I probably missed it and have no
> idea.
I really tire of repeating myself for your sole benefit. Please show
some consideration for other people in the conversation by trying to
listen. Thank-you.
> > I think the first step here would be to allow thin pack generation to
> > accept a bounded range of commits, any of the objects within which may
> > be used as delta base candidates. That way, these "top down" thin packs
> > can be generated. Currently of course it just uses the --not and makes
> > "bottom up" thin packs.
>
> The pack is still almost top-down. It's only the missing delta base
> that are in the other direction, refering to objects you have locally
> and therefore older.
Ok, but right now there's no way to specify that you want a thin pack,
where the allowable base objects are *newer* than the commit range you
wish to include.
What I said in my other e-mail where I showed how well it works taking
a given bundle, and slicing it into a series of thin packs, was that it
seems to add a bit of extra size to the resultant packs - best I got for
slicing up the entire git.git run was about 20%. If this can be
reduced to under 10% (say), then sending bundle slices would be quite
reasonable by default for the benefit of making large fetches
restartable, or even spreadable across multiple mirrors.
The object sorting stuff is something of a distraction; it's required
for download spreading but not for the case at hand now.
Sam
^ permalink raw reply
* Re: [PATCH 2/2 (v3)] reset: make the output more user-friendly.
From: Junio C Hamano @ 2009-08-22 5:44 UTC (permalink / raw)
To: Matthieu Moy; +Cc: git
In-Reply-To: <1250845079-30614-2-git-send-email-Matthieu.Moy@imag.fr>
Matthieu Moy <Matthieu.Moy@imag.fr> writes:
> git reset without argument displays a summary of the remaining
> unstaged changes. The problem with these is that they look like an
> error message, and the format is inconsistant with the format used in
> other places like "git diff --name-status".
>
> This patch mimics the output of "git diff --name-status", and adds a
> header to make it clear the output is informative, and not an error.
>
> It also changes the output of "git add --refresh --verbose" in the same
> way.
>
> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Thanks. Will queue.
However, I'd change the justification.
git reset without argument displays a summary of the local modification,
like this:
$ git reset
Makefile: locally modified
Some people have problems with this; they look like an error message.
This patch makes its output mimic how "git checkout $another_branch"
reports the paths with local modifications. "git add --refresh --verbose"
is changed in the same way.
It also adds a header to make it clear that the output is informative,
and not an error.
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
The output from reset in question is merely an informative side effect, as
opposed to what you actively ask "git diff" to give as its primary output.
As such, your "consistency" argument is pretty weak. There is no reason
to expect that the informative message to resemble one particular format
(namely, --name-status) and not another (e.g. --stat or --name-only), as
you are not explicitly specifying what format to use; nor we would want to
make it customizable--after all it is just a friendly reminder.
Informative output from "git checkout $branch" when there are local
changes is a much better precedent to refer to.
After applying your patch and having compared these two sets of output:
(1) without changes
$ git reset --hard
$ git checkout mm/reset-report
Already on 'mm/reset-report'
$ git reset
$ git add --refresh -v Makefile
(2) with changes
$ echo >>Makefile
$ git add Makefile
$ git checkout mm/reset-report
M Makefile
Already on 'mm/reset-report'
$ git reset
Unstaged changes after reset:
M Makefile
$ git add --refresh -v Makefile
Unstaged changes after refreshing the index:
M Makefile
I am somewhat inclined to suggest that we should drop the new "Unstaged
changes after ..." message, though.
By the way, "Already on .../Switched to ..." noise from "git checkout" is
also very annoying. It is useless to report that the command did exactly
what the user told it to do. Even more annoyingly, "git checkout -q" to
squelch this useless noise also squelches the "here are the paths you have
local changes" reminder, which is much more useful.
But that is a separate topic.
^ permalink raw reply
* [PATCH v3 7/9] sequencer: add "do_commit()" and related functions
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
It adds "struct commit_info", the "next_commit" static variable and
the following functions:
- do_commit()
- set_author_info()
- set_message_source()
- set_pick_subject()
- write_commit_summary_into()
This makes it possible to prepare and perform a commit (without
forking and execing "git commit").
This patch adds some code that comes from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
Compared to the sequencer project, the only change is that "mark"
related (3 lines long) code has been removed from do_commit().
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 214 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 214 insertions(+), 0 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index 71a7fef..61a8f2e 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -5,26 +5,69 @@
#include "refs.h"
#include "diff.h"
#include "unpack-trees.h"
+#include "string-list.h"
+#include "pick.h"
+#include "rerere.h"
+#include "dir.h"
+#include "cache-tree.h"
+#include "utf8.h"
#define SEQ_DIR "rebase-merge"
#define PATCH_FILE git_path(SEQ_DIR "/patch")
+#define MERGE_MSG git_path("MERGE_MSG")
+#define SQUASH_MSG git_path("SQUASH_MSG")
+
+/**********************************************************************
+ * Data structures
+ */
+
+struct user_info {
+ const char *name;
+ const char *mail;
+ const char *time; /* "<timestamp> <timezone>" */
+};
+
+struct commit_info {
+ struct user_info author; /* author info */
+ struct user_info committer; /* not used, but for easy extendability */
+ const char *encoding; /* encoding */
+ char *subject; /* basically the first line of the summary */
+ struct strbuf summary; /* the commit message */
+ char *source; /* source of the commit message, either
+ * "message", "merge", "squash" or a commit SHA1 */
+ char *patch; /* a patch */
+ struct string_list parents; /* list of parents' hex'ed sha1 ids */
+};
+
+/**********************************************************************
+ * Global variables
+ */
static char *reflog;
+static int squash_count = 0;
+
static int allow_dirty = 0, verbosity = 1, advice = 1;
static unsigned char head_sha1[20];
+static struct commit_info next_commit;
+
static const char * const git_sequencer_helper_usage[] = {
"git sequencer--helper --make-patch <commit>",
"git sequencer--helper --reset-hard <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
"git sequencer--helper --fast-forward <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
+ "git sequencer--helper --cherry-pick <commit> [<do-not-commit>]",
NULL
};
+/**********************************************************************
+ * Sequencer functions
+ */
+
static int parse_and_init_tree_desc(const unsigned char *sha1,
struct tree_desc *desc)
{
@@ -162,6 +205,157 @@ static void make_patch(struct commit *commit)
free(args);
}
+/* Commit current index with information next_commit onto parent_sha1. */
+static int do_commit(unsigned char *parent_sha1)
+{
+ int failed;
+ unsigned char tree_sha1[20];
+ unsigned char commit_sha1[20];
+ struct strbuf sbuf;
+ const char *reencoded = NULL;
+
+ if (squash_count) {
+ squash_count = 0;
+ if (file_exists(SQUASH_MSG))
+ unlink(SQUASH_MSG);
+ }
+
+ if (!index_differs_from("HEAD", 0) &&
+ !next_commit.parents.nr)
+ return error("No changes! Do you really want an empty commit?");
+
+ if (!next_commit.author.name || !next_commit.author.mail)
+ return error("Internal error: Author information not set properly.");
+
+ if (write_cache_as_tree(tree_sha1, 0, NULL))
+ return 1;
+
+ if (!next_commit.encoding)
+ next_commit.encoding = xstrdup("utf-8");
+ if (!git_commit_encoding)
+ git_commit_encoding = "utf-8";
+
+ strbuf_init(&sbuf, 8192); /* should avoid reallocs for the headers */
+ strbuf_addf(&sbuf, "tree %s\n", sha1_to_hex(tree_sha1));
+ if (parent_sha1)
+ strbuf_addf(&sbuf, "parent %s\n", sha1_to_hex(parent_sha1));
+ if (next_commit.parents.nr) {
+ int i;
+ for (i = 0; i < next_commit.parents.nr; ++i)
+ strbuf_addf(&sbuf, "parent %s\n",
+ next_commit.parents.items[i].string);
+ }
+ if (!next_commit.author.time) {
+ char time[50];
+ datestamp(time, sizeof(time));
+ next_commit.author.time = xstrdup(time);
+ }
+
+ stripspace(&next_commit.summary, 1);
+
+ /* if encodings differ, reencode whole buffer */
+ if (strcasecmp(git_commit_encoding, next_commit.encoding)) {
+ if ((reencoded = reencode_string(next_commit.author.name,
+ git_commit_encoding, next_commit.encoding))) {
+ free((void *)next_commit.author.name);
+ next_commit.author.name = reencoded;
+ }
+ if ((reencoded = reencode_string(next_commit.summary.buf,
+ git_commit_encoding, next_commit.encoding))) {
+ strbuf_reset(&next_commit.summary);
+ strbuf_addstr(&next_commit.summary, reencoded);
+ }
+ }
+ strbuf_addf(&sbuf, "author %s <%s> %s\n", next_commit.author.name,
+ next_commit.author.mail, next_commit.author.time);
+ strbuf_addf(&sbuf, "committer %s\n", git_committer_info(0));
+ if (!is_encoding_utf8(git_commit_encoding))
+ strbuf_addf(&sbuf, "encoding %s\n", git_commit_encoding);
+ strbuf_addch(&sbuf, '\n');
+ strbuf_addbuf(&sbuf, &next_commit.summary);
+ if (sbuf.buf[sbuf.len-1] != '\n')
+ strbuf_addch(&sbuf, '\n');
+
+ failed = write_sha1_file(sbuf.buf, sbuf.len, commit_type, commit_sha1);
+ strbuf_release(&sbuf);
+ if (failed)
+ return 1;
+
+ if (verbosity > 1)
+ printf("Created %scommit %s\n",
+ parent_sha1 || next_commit.parents.nr ? "" : "initial ",
+ sha1_to_hex(commit_sha1));
+
+ if (update_ref(reflog, "HEAD", commit_sha1, NULL, 0, 0))
+ return error("Could not update HEAD to %s.",
+ sha1_to_hex(commit_sha1));
+
+ return 0;
+}
+
+/*
+ * Fill next_commit.author according to ident.
+ * Ident may have one of the following forms:
+ * "name <e-mail> timestamp timezone\n..."
+ * "name <e-mail> timestamp timezone"
+ * "name <e-mail>"
+ */
+static void set_author_info(const char *ident)
+{
+ const char *tmp1 = strstr(ident, " <");
+ const char *tmp2;
+ char *data;
+ if (!tmp1)
+ return;
+ tmp2 = strstr(tmp1+2, ">");
+ if (!tmp2)
+ return;
+ if (tmp2[1] != 0 && tmp2[1] != ' ')
+ return;
+
+ data = xmalloc(strlen(ident)); /* a trivial upper bound */
+
+ snprintf(data, tmp1-ident+1, "%s", ident);
+ next_commit.author.name = xstrdup(data);
+ snprintf(data, tmp2-tmp1-1, "%s", tmp1+2);
+ next_commit.author.mail = xstrdup(data);
+
+ if (tmp2[1] == 0) {
+ free(data);
+ return;
+ }
+
+ tmp1 = strpbrk(tmp2+2, "\r\n");
+ if (!tmp1)
+ tmp1 = tmp2 + strlen(tmp2);
+
+ snprintf(data, tmp1-tmp2-1, "%s", tmp2+2);
+ next_commit.author.time = xstrdup(data);
+ free(data);
+}
+
+static void set_message_source(const char *source)
+{
+ if (next_commit.source)
+ free(next_commit.source);
+ next_commit.source = xstrdup(source);
+}
+
+/* Set subject, an information for the case of conflict */
+static void set_pick_subject(const char *hex, struct commit *commit)
+{
+ const char *tmp = strstr(commit->buffer, "\n\n");
+ if (tmp) {
+ const char *eol;
+ int len = strlen(hex);
+ tmp += 2;
+ eol = strchrnul(tmp, '\n');
+ next_commit.subject = xmalloc(eol - tmp + len + 5);
+ snprintf(next_commit.subject, eol - tmp + len + 5, "%s... %s",
+ hex, tmp);
+ }
+}
+
/* Return a commit object of "arg" */
static struct commit *get_commit(const char *arg)
{
@@ -198,6 +392,26 @@ static int set_verbosity(int verbose)
return 0;
}
+static int write_commit_summary_into(const char *filename)
+{
+ struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+ int fd = hold_lock_file_for_update(lock, filename, 0);
+ if (fd < 0)
+ return error("Unable to create '%s.lock': %s", filename,
+ strerror(errno));
+ if (write_in_full(fd, next_commit.summary.buf,
+ next_commit.summary.len) < 0)
+ return error("Could not write to %s: %s",
+ filename, strerror(errno));
+ if (commit_lock_file(lock) < 0)
+ return error("Error wrapping up %s", filename);
+ return 0;
+}
+
+/**********************************************************************
+ * Builtin sequencer helper functions
+ */
+
/* v should be "" or "t" or "\d" */
static int parse_verbosity(const char *v)
{
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 6/9] pick: libify "pick_help_msg()"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
This function gives an help message when pick or revert failed.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-revert.c | 23 +----------------------
pick.c | 22 ++++++++++++++++++++++
pick.h | 1 +
3 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/builtin-revert.c b/builtin-revert.c
index 4797ac5..e5250bd 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -142,27 +142,6 @@ static void set_author_ident_env(const char *message)
sha1_to_hex(commit->object.sha1));
}
-static char *help_msg(const unsigned char *sha1)
-{
- static char helpbuf[1024];
- char *msg = getenv("GIT_CHERRY_PICK_HELP");
-
- if (msg)
- return msg;
-
- strcpy(helpbuf, " After resolving the conflicts,\n"
- "mark the corrected paths with 'git add <paths>' "
- "or 'git rm <paths>' and commit the result.");
-
- if (!(flags & PICK_REVERSE)) {
- sprintf(helpbuf + strlen(helpbuf),
- "\nWhen commiting, use the option "
- "'-c %s' to retain authorship and message.",
- find_unique_abbrev(sha1, DEFAULT_ABBREV));
- }
- return helpbuf;
-}
-
static void write_message(struct strbuf *msgbuf, const char *filename)
{
struct lock_file msg_file;
@@ -211,7 +190,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
exit(1);
} else if (failed > 0) {
fprintf(stderr, "Automatic %s failed.%s\n",
- me, help_msg(commit->object.sha1));
+ me, pick_help_msg(commit->object.sha1, flags));
write_message(&msgbuf, git_path("MERGE_MSG"));
rerere();
exit(1);
diff --git a/pick.c b/pick.c
index 058b877..4f882bb 100644
--- a/pick.c
+++ b/pick.c
@@ -208,3 +208,25 @@ int pick_commit(struct commit *pick_commit, int mainline, int flags,
return ret;
}
+
+char *pick_help_msg(const unsigned char *sha1, int flags)
+{
+ static char helpbuf[1024];
+ char *msg = getenv("GIT_CHERRY_PICK_HELP");
+
+ if (msg)
+ return msg;
+
+ strcpy(helpbuf, " After resolving the conflicts,\n"
+ "mark the corrected paths with 'git add <paths>' "
+ "or 'git rm <paths>' and commit the result.");
+
+ if (!(flags & PICK_REVERSE)) {
+ sprintf(helpbuf + strlen(helpbuf),
+ "\nWhen commiting, use the option "
+ "'-c %s' to retain authorship and message.",
+ find_unique_abbrev(sha1, DEFAULT_ABBREV));
+ }
+ return helpbuf;
+}
+
diff --git a/pick.h b/pick.h
index 7a74ad8..115541a 100644
--- a/pick.h
+++ b/pick.h
@@ -9,5 +9,6 @@
/* We don't need a PICK_QUIET. This is done by
* setenv("GIT_MERGE_VERBOSITY", "0", 1); */
extern int pick_commit(struct commit *commit, int mainline, int flags, struct strbuf *msg);
+extern char *pick_help_msg(const unsigned char *sha1, int flags);
#endif
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 9/9] rebase -i: use "git sequencer--helper --cherry-pick"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
instead of "git cherry-pick", as this will make it easier to
port "git-rebase--interactive.sh" to C.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
git-rebase--interactive.sh | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 7651fd6..349ca50 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -147,7 +147,8 @@ pick_one () {
pick_one_preserving_merges "$@" && return
if test ! -z "$REBASE_ROOT"
then
- output git cherry-pick "$@"
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_ff
return
fi
parent_sha1=$(git rev-parse --verify $sha1^) ||
@@ -157,7 +158,8 @@ pick_one () {
git sequencer--helper --fast-forward $sha1 \
"$GIT_REFLOG_ACTION" "$VERBOSE"
else
- output git cherry-pick "$@"
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_ff
fi
}
@@ -269,7 +271,10 @@ pick_one_preserving_merges () {
fi
;;
*)
- output git cherry-pick "$@" ||
+ no_commit=
+ test "a$1" = "a-n" && no_commit=t
+ git sequencer--helper --cherry-pick $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" $no_commit ||
die_with_patch $sha1 "Could not pick $sha1"
;;
esac
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 5/9] revert: libify pick
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
The goal of this commit is to abstract out pick functionnality
into a new pick_commit() function made of code from
"builtin-revert.c".
The new pick_commit() function is in a new "pick.c" file with an
associated "pick.h".
This commit is made of code from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
And it contains some changes suggested by Junio.
The original commit in the sequencer project that introduced
this change is: 94a568a78d243d7a6c13778bc6b7ac1eb46e48cc
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Makefile | 2 +
builtin-revert.c | 272 +++++++++---------------------------------------------
pick.c | 210 +++++++++++++++++++++++++++++++++++++++++
pick.h | 13 +++
4 files changed, 269 insertions(+), 228 deletions(-)
create mode 100644 pick.c
create mode 100644 pick.h
diff --git a/Makefile b/Makefile
index 98dd01d..5e76083 100644
--- a/Makefile
+++ b/Makefile
@@ -445,6 +445,7 @@ LIB_H += pack-refs.h
LIB_H += pack-revindex.h
LIB_H += parse-options.h
LIB_H += patch-ids.h
+LIB_H += pick.h
LIB_H += pkt-line.h
LIB_H += progress.h
LIB_H += quote.h
@@ -533,6 +534,7 @@ LIB_OBJS += parse-options.o
LIB_OBJS += patch-delta.o
LIB_OBJS += patch-ids.o
LIB_OBJS += path.o
+LIB_OBJS += pick.o
LIB_OBJS += pkt-line.o
LIB_OBJS += preload-index.o
LIB_OBJS += pretty.o
diff --git a/builtin-revert.c b/builtin-revert.c
index 151aa6a..4797ac5 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -1,18 +1,14 @@
#include "cache.h"
#include "builtin.h"
-#include "object.h"
#include "commit.h"
#include "tag.h"
-#include "wt-status.h"
-#include "run-command.h"
#include "exec_cmd.h"
#include "utf8.h"
#include "parse-options.h"
-#include "cache-tree.h"
#include "diff.h"
#include "revision.h"
#include "rerere.h"
-#include "merge-recursive.h"
+#include "pick.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -35,25 +31,23 @@ static const char * const cherry_pick_usage[] = {
NULL
};
-static int edit, no_replay, no_commit, mainline, signoff;
-static enum { REVERT, CHERRY_PICK } action;
+static int edit, no_commit, mainline, signoff;
+static int flags;
static struct commit *commit;
-static const char *me;
-
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
static void parse_args(int argc, const char **argv)
{
const char * const * usage_str =
- action == REVERT ? revert_usage : cherry_pick_usage;
+ flags & PICK_REVERSE ? revert_usage : cherry_pick_usage;
unsigned char sha1[20];
const char *arg;
int noop;
struct option options[] = {
OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"),
- OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"),
+ OPT_BIT('x', NULL, &flags, "append commit name when cherry-picking", PICK_ADD_NOTE),
OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
@@ -77,42 +71,12 @@ static void parse_args(int argc, const char **argv)
die ("'%s' does not point to a commit", arg);
}
-static char *get_oneline(const char *message)
-{
- char *result;
- const char *p = message, *abbrev, *eol;
- int abbrev_len, oneline_len;
-
- if (!p)
- die ("Could not read commit message of %s",
- sha1_to_hex(commit->object.sha1));
- while (*p && (*p != '\n' || p[1] != '\n'))
- p++;
-
- if (*p) {
- p += 2;
- for (eol = p + 1; *eol && *eol != '\n'; eol++)
- ; /* do nothing */
- } else
- eol = p;
- abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
- abbrev_len = strlen(abbrev);
- oneline_len = eol - p;
- result = xmalloc(abbrev_len + 5 + oneline_len);
- memcpy(result, abbrev, abbrev_len);
- memcpy(result + abbrev_len, "... ", 4);
- memcpy(result + abbrev_len + 4, p, oneline_len);
- result[abbrev_len + 4 + oneline_len] = '\0';
- return result;
-}
-
static char *get_encoding(const char *message)
{
const char *p = message, *eol;
if (!p)
- die ("Could not read commit message of %s",
- sha1_to_hex(commit->object.sha1));
+ return NULL;
while (*p && *p != '\n') {
for (eol = p + 1; *eol && *eol != '\n'; eol++)
; /* do nothing */
@@ -128,30 +92,6 @@ static char *get_encoding(const char *message)
return NULL;
}
-static struct lock_file msg_file;
-static int msg_fd;
-
-static void add_to_msg(const char *string)
-{
- int len = strlen(string);
- if (write_in_full(msg_fd, string, len) < 0)
- die_errno ("Could not write to MERGE_MSG");
-}
-
-static void add_message_to_msg(const char *message)
-{
- const char *p = message;
- while (*p && (*p != '\n' || p[1] != '\n'))
- p++;
-
- if (!*p)
- add_to_msg(sha1_to_hex(commit->object.sha1));
-
- p += 2;
- add_to_msg(p);
- return;
-}
-
static void set_author_ident_env(const char *message)
{
const char *p = message;
@@ -214,7 +154,7 @@ static char *help_msg(const unsigned char *sha1)
"mark the corrected paths with 'git add <paths>' "
"or 'git rm <paths>' and commit the result.");
- if (action == CHERRY_PICK) {
+ if (!(flags & PICK_REVERSE)) {
sprintf(helpbuf + strlen(helpbuf),
"\nWhen commiting, use the option "
"'-c %s' to retain authorship and message.",
@@ -223,187 +163,68 @@ static char *help_msg(const unsigned char *sha1)
return helpbuf;
}
-static struct tree *empty_tree(void)
+static void write_message(struct strbuf *msgbuf, const char *filename)
{
- struct tree *tree = xcalloc(1, sizeof(struct tree));
-
- tree->object.parsed = 1;
- tree->object.type = OBJ_TREE;
- pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
- return tree;
+ struct lock_file msg_file;
+ int msg_fd;
+ msg_fd = hold_lock_file_for_update(&msg_file, filename,
+ LOCK_DIE_ON_ERROR);
+ if (write_in_full(msg_fd, msgbuf->buf, msgbuf->len) < 0)
+ die_errno("Could not write to %s.", filename);
+ strbuf_release(msgbuf);
+ if (commit_lock_file(&msg_file) < 0)
+ die("Error wrapping up %s", filename);
}
static int revert_or_cherry_pick(int argc, const char **argv)
{
- unsigned char head[20];
- struct commit *base, *next, *parent;
- int i, index_fd, clean;
- char *oneline, *reencoded_message = NULL;
- const char *message, *encoding;
- char *defmsg = git_pathdup("MERGE_MSG");
- struct merge_options o;
- struct tree *result, *next_tree, *base_tree, *head_tree;
- static struct lock_file index_lock;
+ const char *me;
+ struct strbuf msgbuf;
+ char *reencoded_message = NULL;
+ const char *encoding;
+ int failed;
git_config(git_default_config, NULL);
- me = action == REVERT ? "revert" : "cherry-pick";
+ me = flags & PICK_REVERSE ? "revert" : "cherry-pick";
setenv(GIT_REFLOG_ACTION, me, 0);
parse_args(argc, argv);
- /* this is copied from the shell script, but it's never triggered... */
- if (action == REVERT && !no_replay)
- die("revert is incompatible with replay");
-
if (read_cache() < 0)
die("git %s: failed to read the index", me);
- if (no_commit) {
- /*
- * We do not intend to commit immediately. We just want to
- * merge the differences in, so let's compute the tree
- * that represents the "current" state for merge-recursive
- * to work on.
- */
- if (write_cache_as_tree(head, 0, NULL))
- die ("Your index file is unmerged.");
- } else {
- if (get_sha1("HEAD", head))
- die ("You do not have a valid HEAD");
- if (index_differs_from("HEAD", 0))
- die ("Dirty index: cannot %s", me);
- }
- discard_cache();
-
- index_fd = hold_locked_index(&index_lock, 1);
+ if (!no_commit && index_differs_from("HEAD", 0))
+ die ("Dirty index: cannot %s", me);
- if (!commit->parents) {
- if (action == REVERT)
- die ("Cannot revert a root commit");
- parent = NULL;
- }
- else if (commit->parents->next) {
- /* Reverting or cherry-picking a merge commit */
- int cnt;
- struct commit_list *p;
-
- if (!mainline)
- die("Commit %s is a merge but no -m option was given.",
- sha1_to_hex(commit->object.sha1));
-
- for (cnt = 1, p = commit->parents;
- cnt != mainline && p;
- cnt++)
- p = p->next;
- if (cnt != mainline || !p)
- die("Commit %s does not have parent %d",
- sha1_to_hex(commit->object.sha1), mainline);
- parent = p->item;
- } else if (0 < mainline)
- die("Mainline was specified but commit %s is not a merge.",
- sha1_to_hex(commit->object.sha1));
- else
- parent = commit->parents->item;
-
- if (!(message = commit->buffer))
- die ("Cannot get commit message for %s",
+ if (!commit->buffer)
+ return error("Cannot get commit message for %s",
sha1_to_hex(commit->object.sha1));
-
- if (parent && parse_commit(parent) < 0)
- die("%s: cannot parse parent commit %s",
- me, sha1_to_hex(parent->object.sha1));
-
- /*
- * "commit" is an existing commit. We would want to apply
- * the difference it introduces since its first parent "prev"
- * on top of the current HEAD if we are cherry-pick. Or the
- * reverse of it if we are revert.
- */
-
- msg_fd = hold_lock_file_for_update(&msg_file, defmsg,
- LOCK_DIE_ON_ERROR);
-
- encoding = get_encoding(message);
+ encoding = get_encoding(commit->buffer);
if (!encoding)
encoding = "UTF-8";
if (!git_commit_encoding)
git_commit_encoding = "UTF-8";
- if ((reencoded_message = reencode_string(message,
+ if ((reencoded_message = reencode_string(commit->buffer,
git_commit_encoding, encoding)))
- message = reencoded_message;
-
- oneline = get_oneline(message);
-
- if (action == REVERT) {
- char *oneline_body = strchr(oneline, ' ');
+ commit->buffer = reencoded_message;
- base = commit;
- next = parent;
- add_to_msg("Revert \"");
- add_to_msg(oneline_body + 1);
- add_to_msg("\"\n\nThis reverts commit ");
- add_to_msg(sha1_to_hex(commit->object.sha1));
-
- if (commit->parents->next) {
- add_to_msg(", reversing\nchanges made to ");
- add_to_msg(sha1_to_hex(parent->object.sha1));
- }
- add_to_msg(".\n");
- } else {
- base = parent;
- next = commit;
- set_author_ident_env(message);
- add_message_to_msg(message);
- if (no_replay) {
- add_to_msg("(cherry picked from commit ");
- add_to_msg(sha1_to_hex(commit->object.sha1));
- add_to_msg(")\n");
- }
- }
-
- read_cache();
- init_merge_options(&o);
- o.branch1 = "HEAD";
- o.branch2 = oneline;
-
- head_tree = parse_tree_indirect(head);
- next_tree = next ? next->tree : empty_tree();
- base_tree = base ? base->tree : empty_tree();
-
- clean = merge_trees(&o,
- head_tree,
- next_tree, base_tree, &result);
-
- if (active_cache_changed &&
- (write_cache(index_fd, active_cache, active_nr) ||
- commit_locked_index(&index_lock)))
- die("%s: Unable to write new index file", me);
- rollback_lock_file(&index_lock);
-
- if (!clean) {
- add_to_msg("\nConflicts:\n\n");
- for (i = 0; i < active_nr;) {
- struct cache_entry *ce = active_cache[i++];
- if (ce_stage(ce)) {
- add_to_msg("\t");
- add_to_msg(ce->name);
- add_to_msg("\n");
- while (i < active_nr && !strcmp(ce->name,
- active_cache[i]->name))
- i++;
- }
- }
- if (commit_lock_file(&msg_file) < 0)
- die ("Error wrapping up %s", defmsg);
+ failed = pick_commit(commit, mainline, flags, &msgbuf);
+ if (failed < 0) {
+ exit(1);
+ } else if (failed > 0) {
fprintf(stderr, "Automatic %s failed.%s\n",
me, help_msg(commit->object.sha1));
+ write_message(&msgbuf, git_path("MERGE_MSG"));
rerere();
exit(1);
}
- if (commit_lock_file(&msg_file) < 0)
- die ("Error wrapping up %s", defmsg);
+ if (!(flags & PICK_REVERSE))
+ set_author_ident_env(commit->buffer);
+ free(reencoded_message);
+
fprintf(stderr, "Finished one %s.\n", me);
+ write_message(&msgbuf, git_path("MERGE_MSG"));
+
/*
- *
* If we are cherry-pick, and if the merge did not result in
* hand-editing, we will hit this commit and inherit the original
* author date and name.
@@ -421,14 +242,11 @@ static int revert_or_cherry_pick(int argc, const char **argv)
args[i++] = "-s";
if (!edit) {
args[i++] = "-F";
- args[i++] = defmsg;
+ args[i++] = git_path("MERGE_MSG");
}
args[i] = NULL;
return execv_git_cmd(args);
}
- free(reencoded_message);
- free(defmsg);
-
return 0;
}
@@ -436,14 +254,12 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
{
if (isatty(0))
edit = 1;
- no_replay = 1;
- action = REVERT;
+ flags = PICK_REVERSE | PICK_ADD_NOTE;
return revert_or_cherry_pick(argc, argv);
}
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
{
- no_replay = 0;
- action = CHERRY_PICK;
+ flags = 0;
return revert_or_cherry_pick(argc, argv);
}
diff --git a/pick.c b/pick.c
new file mode 100644
index 0000000..058b877
--- /dev/null
+++ b/pick.c
@@ -0,0 +1,210 @@
+#include "cache.h"
+#include "commit.h"
+#include "run-command.h"
+#include "cache-tree.h"
+#include "pick.h"
+#include "merge-recursive.h"
+
+static struct commit *commit;
+
+static char *get_oneline(const char *message)
+{
+ char *result;
+ const char *p = message, *abbrev, *eol;
+ int abbrev_len, oneline_len;
+
+ if (!p)
+ return NULL;
+ while (*p && (*p != '\n' || p[1] != '\n'))
+ p++;
+
+ if (*p) {
+ p += 2;
+ for (eol = p + 1; *eol && *eol != '\n'; eol++)
+ ; /* do nothing */
+ } else
+ eol = p;
+ abbrev = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
+ abbrev_len = strlen(abbrev);
+ oneline_len = eol - p;
+ result = xmalloc(abbrev_len + 5 + oneline_len);
+ memcpy(result, abbrev, abbrev_len);
+ memcpy(result + abbrev_len, "... ", 4);
+ memcpy(result + abbrev_len + 4, p, oneline_len);
+ result[abbrev_len + 4 + oneline_len] = '\0';
+ return result;
+}
+
+static void add_message_to_msg(struct strbuf *msg, const char *message)
+{
+ const char *p = message;
+ while (*p && (*p != '\n' || p[1] != '\n'))
+ p++;
+
+ if (!*p)
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+
+ p += 2;
+ strbuf_addstr(msg, p);
+ return;
+}
+
+static struct tree *empty_tree(void)
+{
+ struct tree *tree = xcalloc(1, sizeof(struct tree));
+
+ tree->object.parsed = 1;
+ tree->object.type = OBJ_TREE;
+ pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
+ return tree;
+}
+
+/*
+ * Pick changes introduced by "commit" argument into current working
+ * tree and index.
+ *
+ * Return 0 on success.
+ * Return negative value on error before picking,
+ * and a positive value after picking,
+ * and return 1 if and only if a conflict occurs but no other error.
+ */
+int pick_commit(struct commit *pick_commit, int mainline, int flags,
+ struct strbuf *msg)
+{
+ unsigned char head[20];
+ struct commit *base, *next, *parent;
+ int i, index_fd, clean;
+ int ret = 0;
+ char *oneline;
+ const char *message;
+ struct merge_options o;
+ struct tree *result, *next_tree, *base_tree, *head_tree;
+ static struct lock_file index_lock;
+
+ strbuf_init(msg, 0);
+ commit = pick_commit;
+
+ /*
+ * Let's compute the tree that represents the "current" state
+ * for merge-recursive to work on.
+ */
+ if (write_cache_as_tree(head, 0, NULL))
+ return error("Your index file is unmerged.");
+ discard_cache();
+
+ index_fd = hold_locked_index(&index_lock, 0);
+ if (index_fd < 0)
+ return error("Unable to create locked index: %s",
+ strerror(errno));
+
+ if (!commit->parents) {
+ if (flags & PICK_REVERSE)
+ return error("Cannot revert a root commit");
+ parent = NULL;
+ }
+ else if (commit->parents->next) {
+ /* Reverting or cherry-picking a merge commit */
+ int cnt;
+ struct commit_list *p;
+
+ if (!mainline)
+ return error("Commit %s is a merge but no mainline was given.",
+ sha1_to_hex(commit->object.sha1));
+
+ for (cnt = 1, p = commit->parents;
+ cnt != mainline && p;
+ cnt++)
+ p = p->next;
+ if (cnt != mainline || !p)
+ return error("Commit %s does not have parent %d",
+ sha1_to_hex(commit->object.sha1),
+ mainline);
+ parent = p->item;
+ } else if (0 < mainline)
+ return error("Mainline was specified but commit %s is not a merge.",
+ sha1_to_hex(commit->object.sha1));
+ else
+ parent = commit->parents->item;
+
+ if (!(message = commit->buffer))
+ return error("Cannot get commit message for %s",
+ sha1_to_hex(commit->object.sha1));
+
+ if (parent && parse_commit(parent) < 0)
+ return error("Cannot parse parent commit %s",
+ sha1_to_hex(parent->object.sha1));
+
+ oneline = get_oneline(message);
+
+ if (flags & PICK_REVERSE) {
+ char *oneline_body = strchr(oneline, ' ');
+
+ base = commit;
+ next = parent;
+ strbuf_addstr(msg, "Revert \"");
+ strbuf_addstr(msg, oneline_body + 1);
+ strbuf_addstr(msg, "\"\n\nThis reverts commit ");
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+
+ if (commit->parents->next) {
+ strbuf_addstr(msg, ", reversing\nchanges made to ");
+ strbuf_addstr(msg, sha1_to_hex(parent->object.sha1));
+ }
+ strbuf_addstr(msg, ".\n");
+ } else {
+ base = parent;
+ next = commit;
+ add_message_to_msg(msg, message);
+ if (flags & PICK_ADD_NOTE) {
+ strbuf_addstr(msg, "(cherry picked from commit ");
+ strbuf_addstr(msg, sha1_to_hex(commit->object.sha1));
+ strbuf_addstr(msg, ")\n");
+ }
+ }
+
+ read_cache();
+ init_merge_options(&o);
+ o.branch1 = "HEAD";
+ o.branch2 = oneline;
+
+ head_tree = parse_tree_indirect(head);
+ next_tree = next ? next->tree : empty_tree();
+ base_tree = base ? base->tree : empty_tree();
+
+ clean = merge_trees(&o,
+ head_tree,
+ next_tree, base_tree, &result);
+
+ if (active_cache_changed &&
+ (write_cache(index_fd, active_cache, active_nr) ||
+ commit_locked_index(&index_lock))) {
+ error("Unable to write new index file");
+ return 2;
+ }
+ rollback_lock_file(&index_lock);
+
+ if (!clean) {
+ strbuf_addstr(msg, "\nConflicts:\n\n");
+ for (i = 0; i < active_nr;) {
+ struct cache_entry *ce = active_cache[i++];
+ if (ce_stage(ce)) {
+ strbuf_addstr(msg, "\t");
+ strbuf_addstr(msg, ce->name);
+ strbuf_addstr(msg, "\n");
+ while (i < active_nr && !strcmp(ce->name,
+ active_cache[i]->name))
+ i++;
+ }
+ }
+ ret = 1;
+ }
+ free(oneline);
+
+ discard_cache();
+ if (read_cache() < 0) {
+ error("Cannot read the index");
+ return 2;
+ }
+
+ return ret;
+}
diff --git a/pick.h b/pick.h
new file mode 100644
index 0000000..7a74ad8
--- /dev/null
+++ b/pick.h
@@ -0,0 +1,13 @@
+#ifndef PICK_H
+#define PICK_H
+
+#include "commit.h"
+
+/* Pick flags: */
+#define PICK_REVERSE 1 /* pick the reverse changes ("revert") */
+#define PICK_ADD_NOTE 2 /* add note about original commit (unless conflict) */
+/* We don't need a PICK_QUIET. This is done by
+ * setenv("GIT_MERGE_VERBOSITY", "0", 1); */
+extern int pick_commit(struct commit *commit, int mainline, int flags, struct strbuf *msg);
+
+#endif
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 8/9] sequencer: add "--cherry-pick" option to "git sequencer--helper"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
This patch adds some code that comes from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
Most of the code from do_cherry_pick() is taken from the
sequencer insn_pick_act() function.
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 71 +++++++++++++++++++++++++++++++++++++------
1 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index 61a8f2e..291ba18 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -60,7 +60,8 @@ static const char * const git_sequencer_helper_usage[] = {
"<verbosity> [<allow-dirty>]",
"git sequencer--helper --fast-forward <commit> <reflog-msg> "
"<verbosity> [<allow-dirty>]",
- "git sequencer--helper --cherry-pick <commit> [<do-not-commit>]",
+ "git sequencer--helper --cherry-pick <commit> <reflog-msg> "
+ "<verbosity> [<do-not-commit>]",
NULL
};
@@ -288,7 +289,7 @@ static int do_commit(unsigned char *parent_sha1)
if (update_ref(reflog, "HEAD", commit_sha1, NULL, 0, 0))
return error("Could not update HEAD to %s.",
- sha1_to_hex(commit_sha1));
+ sha1_to_hex(commit_sha1));
return 0;
}
@@ -408,6 +409,46 @@ static int write_commit_summary_into(const char *filename)
return 0;
}
+static int do_cherry_pick(char *cp_commit, int no_commit)
+{
+ struct commit *commit;
+ int failed;
+ const char *author;
+
+ if (get_sha1("HEAD", head_sha1))
+ return error("You do not have a valid HEAD.");
+
+ commit = get_commit(cp_commit);
+ if (!commit)
+ return 1;
+
+ set_pick_subject(cp_commit, commit);
+
+ failed = pick_commit(commit, 0, 0, &next_commit.summary);
+
+ set_message_source(sha1_to_hex(commit->object.sha1));
+ author = strstr(commit->buffer, "\nauthor ");
+ if (author)
+ set_author_info(author + 8);
+
+ /* We do not want extra Conflicts: lines on cherry-pick,
+ so just take the old commit message. */
+ if (failed) {
+ strbuf_setlen(&next_commit.summary, 0);
+ strbuf_addstr(&next_commit.summary,
+ strstr(commit->buffer, "\n\n") + 2);
+ rerere();
+ make_patch(commit);
+ write_commit_summary_into(MERGE_MSG);
+ return error(pick_help_msg(commit->object.sha1, 0));
+ }
+
+ if (!no_commit && do_commit(head_sha1))
+ return error("Could not commit.");
+
+ return 0;
+}
+
/**********************************************************************
* Builtin sequencer helper functions
*/
@@ -436,6 +477,7 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
char *patch_commit = NULL;
char *reset_commit = NULL;
char *ff_commit = NULL;
+ char *cp_commit = NULL;
struct option options[] = {
OPT_STRING(0, "make-patch", &patch_commit, "commit",
"create a patch from commit"),
@@ -443,6 +485,8 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
"reset to commit"),
OPT_STRING(0, "fast-forward", &ff_commit, "commit",
"fast forward to commit"),
+ OPT_STRING(0, "cherry-pick", &cp_commit, "commit",
+ "cherry pick commit"),
OPT_END()
};
@@ -459,19 +503,15 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 0;
}
- if (ff_commit || reset_commit) {
+ if (cp_commit || ff_commit || reset_commit) {
unsigned char sha1[20];
- char *commit = ff_commit ? ff_commit : reset_commit;
+ char *commit;
+ int opt_arg = 0;
if (argc != 2 && argc != 3)
usage_with_options(git_sequencer_helper_usage,
options);
- if (get_sha1(commit, sha1)) {
- error("Could not find '%s'", commit);
- return 1;
- }
-
reflog = (char *)argv[0];
if (parse_verbosity(argv[1])) {
@@ -480,7 +520,18 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
}
if (argc == 3 && *argv[2] && strcmp(argv[2], "0"))
- allow_dirty = 1;
+ opt_arg = 1;
+
+ if (cp_commit)
+ return do_cherry_pick(cp_commit, opt_arg);
+
+ allow_dirty = opt_arg;
+
+ commit = ff_commit ? ff_commit : reset_commit;
+ if (get_sha1(commit, sha1)) {
+ error("Could not find '%s'", commit);
+ return 1;
+ }
if (ff_commit)
return do_fast_forward(sha1);
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 3/9] sequencer: let "git sequencer--helper" callers set "allow_dirty"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
This flag can be set when using --reset-hard or --fast-forward, and
in this case changes in the work tree will be kept.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index bd72f65..71a7fef 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -18,8 +18,10 @@ static unsigned char head_sha1[20];
static const char * const git_sequencer_helper_usage[] = {
"git sequencer--helper --make-patch <commit>",
- "git sequencer--helper --reset-hard <commit> <reflog-msg> <verbosity>",
- "git sequencer--helper --fast-forward <commit> <reflog-msg> <verbosity>",
+ "git sequencer--helper --reset-hard <commit> <reflog-msg> "
+ "<verbosity> [<allow-dirty>]",
+ "git sequencer--helper --fast-forward <commit> <reflog-msg> "
+ "<verbosity> [<allow-dirty>]",
NULL
};
@@ -247,7 +249,7 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
unsigned char sha1[20];
char *commit = ff_commit ? ff_commit : reset_commit;
- if (argc != 2)
+ if (argc != 2 && argc != 3)
usage_with_options(git_sequencer_helper_usage,
options);
@@ -263,6 +265,9 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 1;
}
+ if (argc == 3 && *argv[2] && strcmp(argv[2], "0"))
+ allow_dirty = 1;
+
if (ff_commit)
return do_fast_forward(sha1);
else
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 4/9] rebase -i: use "git sequencer--helper --fast-forward"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
when fast forwarding.
Note that in the first hunk of this patch, there was this line:
test "a$1" = a-n && output git reset --soft $current_sha1
but the test always failed.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
git-rebase--interactive.sh | 11 +++--------
1 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 0041994..7651fd6 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -154,11 +154,8 @@ pick_one () {
die "Could not get the parent of $sha1"
current_sha1=$(git rev-parse --verify HEAD)
if test "$no_ff$current_sha1" = "$parent_sha1"; then
- git sequencer--helper --reset-hard $sha1 \
+ git sequencer--helper --fast-forward $sha1 \
"$GIT_REFLOG_ACTION" "$VERBOSE"
- test "a$1" = a-n && output git reset --soft $current_sha1
- sha1=$(git rev-parse --short $sha1)
- output warn Fast forward to $sha1
else
output git cherry-pick "$@"
fi
@@ -238,10 +235,8 @@ pick_one_preserving_merges () {
done
case $fast_forward in
t)
- output warn "Fast forward to $sha1"
- git sequencer--helper --reset-hard $sha1 \
- "$GIT_REFLOG_ACTION" "$VERBOSE" ||
- die "Cannot fast forward to $sha1"
+ git sequencer--helper --fast-forward $sha1 \
+ "$GIT_REFLOG_ACTION" "$VERBOSE" || exit
;;
f)
first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 2/9] sequencer: add "--fast-forward" option to "git sequencer--helper"
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
This new option uses the "do_fast_forward()" function to perform
a fast forward.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index 0cd7e98..bd72f65 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -19,6 +19,7 @@ static unsigned char head_sha1[20];
static const char * const git_sequencer_helper_usage[] = {
"git sequencer--helper --make-patch <commit>",
"git sequencer--helper --reset-hard <commit> <reflog-msg> <verbosity>",
+ "git sequencer--helper --fast-forward <commit> <reflog-msg> <verbosity>",
NULL
};
@@ -218,11 +219,14 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
{
char *patch_commit = NULL;
char *reset_commit = NULL;
+ char *ff_commit = NULL;
struct option options[] = {
OPT_STRING(0, "make-patch", &patch_commit, "commit",
"create a patch from commit"),
OPT_STRING(0, "reset-hard", &reset_commit, "commit",
"reset to commit"),
+ OPT_STRING(0, "fast-forward", &ff_commit, "commit",
+ "fast forward to commit"),
OPT_END()
};
@@ -239,15 +243,16 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 0;
}
- if (reset_commit) {
+ if (ff_commit || reset_commit) {
unsigned char sha1[20];
+ char *commit = ff_commit ? ff_commit : reset_commit;
if (argc != 2)
usage_with_options(git_sequencer_helper_usage,
options);
- if (get_sha1(reset_commit, sha1)) {
- error("Could not find '%s'", reset_commit);
+ if (get_sha1(commit, sha1)) {
+ error("Could not find '%s'", commit);
return 1;
}
@@ -258,7 +263,10 @@ int cmd_sequencer__helper(int argc, const char **argv, const char *prefix)
return 1;
}
- return reset_almost_hard(sha1);
+ if (ff_commit)
+ return do_fast_forward(sha1);
+ else
+ return reset_almost_hard(sha1);
}
usage_with_options(git_sequencer_helper_usage, options);
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 1/9] sequencer: add "do_fast_forward()" to perform a fast forward
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <20090822041157.4261.92491.chriscool@tuxfamily.org>
From: Stephan Beyer <s-beyer@gmx.net>
This code is taken from the sequencer GSoC project:
git://repo.or.cz/git/sbeyer.git
(commit e7b8dab0c2a73ade92017a52bb1405ea1534ef20)
but the messages have been changed to be the same as those
displayed by git-rebase--interactive.sh.
Mentored-by: Daniel Barkalow <barkalow@iabervon.org>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-sequencer--helper.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/builtin-sequencer--helper.c b/builtin-sequencer--helper.c
index be030bc..0cd7e98 100644
--- a/builtin-sequencer--helper.c
+++ b/builtin-sequencer--helper.c
@@ -171,6 +171,15 @@ static struct commit *get_commit(const char *arg)
return lookup_commit_reference(sha1);
}
+static int do_fast_forward(const unsigned char *sha)
+{
+ if (reset_almost_hard(sha))
+ return error("Cannot fast forward to %s", sha1_to_hex(sha));
+ if (verbosity > 1)
+ printf("Fast forward to %s\n", sha1_to_hex(sha));
+ return 0;
+}
+
static int set_verbosity(int verbose)
{
char tmp[] = "0";
--
1.6.4.271.ge010d
^ permalink raw reply related
* [PATCH v3 0/9] more changes to port rebase -i to C using sequencer code
From: Christian Couder @ 2009-08-22 4:16 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
This is another reroll of the series I first sent on August the 12th.
The only changes since v2 are in the commit messages. References to the
pick() function have been replaced by references to pick_commit(), and I
tried to describe the purpose of the patch first.
Christian Couder (5):
sequencer: add "--fast-forward" option to "git sequencer--helper"
sequencer: let "git sequencer--helper" callers set "allow_dirty"
rebase -i: use "git sequencer--helper --fast-forward"
pick: libify "pick_help_msg()"
rebase -i: use "git sequencer--helper --cherry-pick"
Stephan Beyer (4):
sequencer: add "do_fast_forward()" to perform a fast forward
revert: libify pick
sequencer: add "do_commit()" and related functions
sequencer: add "--cherry-pick" option to "git sequencer--helper"
Makefile | 2 +
builtin-revert.c | 293 ++++++-----------------------------------
builtin-sequencer--helper.c | 305 +++++++++++++++++++++++++++++++++++++++++--
git-rebase--interactive.sh | 22 ++--
pick.c | 232 ++++++++++++++++++++++++++++++++
pick.h | 14 ++
6 files changed, 599 insertions(+), 269 deletions(-)
create mode 100644 pick.c
create mode 100644 pick.h
^ permalink raw reply
* Re: [PATCH v2 5/9] revert: libify pick
From: Christian Couder @ 2009-08-22 4:35 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Johannes Schindelin, Stephan Beyer, Daniel Barkalow,
Jakub Narebski
In-Reply-To: <7v8whdip1l.fsf@alter.siamese.dyndns.org>
On Friday 21 August 2009, Junio C Hamano wrote:
> Christian Couder <chriscool@tuxfamily.org> writes:
> > From: Stephan Beyer <s-beyer@gmx.net>
> >
> > This commit is made of code from the sequencer GSoC project:
> >
> > git://repo.or.cz/git/sbeyer.git
> >
> > (commit 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079)
> >
> > The goal of this commit is to abstract out pick functionnality
> > into a new pick() function made of code from "builtin-revert.c".
> >
> > The new pick() function is in a new "pick.c" file with an
> > associated "pick.h".
>
> Is it pick() or pick_commit()?
It is pick_commit(). Sorry I didn't properly update the commit message.
> By the way, this comment applies to other messages in the series, but do
> these original commits by Stephan lack any meaningful messages?
Well, in Stephan's repo the commit
(94a568a78d243d7a6c13778bc6b7ac1eb46e48cc) that created the pick.c and
pick.h files had this message:
------
Libify cherry-pick and revert.
A poor start.
------
(Note that I have seen far worse commit messages in other GSoC students'
repo.)
And then quite a few other commits improved on this one, and the whole gives
the code that is in this patch.
> I would
> actually have expected to see a commit log message that looks more like:
>
> From: Stephan Beyer <...>
>
> Meaningful log message Stephan describes what this commit does in
> sufficient detail, perhaps with clarification and rewording by
> Christian.
>
> Second and subsequent paragraph to explain it as necessary.
>
> [cc: this is based on 5a78908b70ceb5a4ea9fd4b82f07ceba1f019079
> from Stephan's git://repo.or.cz/git/sbeyer.git]
>
> Signed-off-by: ...
>
> The point is that the "origin info" would be a side-note, not the first
> and the most important thing in the message.
I tried to improve some commit messages like this in the v3 that will follow
this email.
Thanks,
Christian.
^ permalink raw reply
* Re: [PATCH 0/6 RFC] Series to correct xutils incomplete line handling.
From: Thell Fowler @ 2009-08-22 4:23 UTC (permalink / raw)
To: Alex Riesen; +Cc: Thell Fowler, Johannes Schindelin, git
In-Reply-To: <81b0412b0908211516l4db79249h180e50ffb8e2c1ab@mail.gmail.com>
Alex Riesen (raa.lkml@gmail.com) wrote on Aug 21, 2009:
> On Fri, Aug 21, 2009 at 19:39, Thell Fowler<git@tbfowler.name> wrote:
> > What is _REALLY_ odd is that it didn't make any tests fail in the test
> > dir using master, next, and pu.
>
> The test suite has a very good coverage, but it surely is not complete.
>
Well, two lessons learned...
1) Don't do isolated tests and count on the bundled tests to catch the
corner cases.
2) Write more tests.
> > Perhaps someone can explain what I did wrong when testing?
> >
> > git checkout master
> > make -s clean && make -s all && make -s install && cd t && make
>
> This should have worked. Although I prefer just:
>
> $ make -j4 && make test -j16
>
Good to know I was on the right track. Thanks.
--
Thell
^ permalink raw reply
* Re: hitting home directory's parent
From: Nguyen Thai Ngoc Duy @ 2009-08-22 4:10 UTC (permalink / raw)
To: Daniel Convissor; +Cc: Git Mailing List
In-Reply-To: <20090821200503.GA19660@panix.com>
On Sat, Aug 22, 2009 at 3:05 AM, Daniel
Convissor<danielc@analysisandsolutions.com> wrote:
> Hi:
>
> I just installed git in my Cygwin installation for the first time. The
> git version is 1.6.1.2, which is the latest version they have. When I
> enter one of the following commands:
> git --help
> git config --global user.name "Daniel Convissor"
>
> I get this error:
> fatal: Cannot change to /home/danielc/..: Permission denied
>
> Though "git --version" executes fine.
>
> I've been using Cygwin for many years and no other program has ever
> produced this issue for me. For example, svn --help, ls --help, etc work
> just fine.
>
> Why is git venturing into to the home directory's parent directory? Is
> this a bug? If not, is this really necessary?
I guess it tried to find .git directory upward. I think you can set
GIT_CEILING_DIRECTORIES to make it stop at /home/danielc. Excerpt from
git.txt
-'GIT_CEILING_DIRECTORIES'::
This should be a colon-separated list of absolute paths.
If set, it is a list of directories that git should not chdir
up into while looking for a repository directory.
It will not exclude the current working directory or
a GIT_DIR set on the command line or in the environment.
(Useful for excluding slow-loading network directories.)
-
Duy
^ permalink raw reply
* Re: Continue git clone after interruption
From: Nicolas Pitre @ 2009-08-22 3:37 UTC (permalink / raw)
To: Sam Vilain
Cc: Jakub Narebski, Tomasz Kontusz, git, Johannes Schindelin,
Scott Chacon
In-Reply-To: <1250896025.19039.7.camel@maia.lan>
On Sat, 22 Aug 2009, Sam Vilain wrote:
> On Fri, 2009-08-21 at 17:07 -0400, Nicolas Pitre wrote:
> > > 2. There is support in git pack format to do 'deepening' of shallow
> > > clone, which means that git can generate incrementals in top-down
> > > order, _similar to how objects are ordered in packfile_.
> >
> > Well... the pack format was not meant for that "support". The fact
> > that
> > the typical object order used by pack-objects when serving fetch
> > request
> > is amenable to incremental top-down updates is rather coincidental
> > and
> > not really planned.
>
> Mmm. And the problem with 'thin' packs is that they normally allow
> deltas the other way.
Sure. The pack format is flexible.
> I think the first step here would be to allow thin pack generation to
> accept a bounded range of commits, any of the objects within which may
> be used as delta base candidates. That way, these "top down" thin packs
> can be generated. Currently of course it just uses the --not and makes
> "bottom up" thin packs.
The pack is still almost top-down. It's only the missing delta base
that are in the other direction, refering to objects you have locally
and therefore older.
> > > Another solution would be to try to come up with some sort of stable
> > > sorting of objects so that packfile generated for the same
> > > parameters (endpoints) would be always byte-for-byte the same. But
> > > that might be difficult, or even impossible.
> >
> > And I don't want to commit to that either. Having some flexibility
> > in object ordering makes it possible to improve on the packing
> > heuristics.
>
> You don't have to lose that for storage. It's only for generating the
> thin packs that it matters;
What matters?
> also, the restriction is relaxed when it
> comes to objects which are all being sent in the same pack, which can
> freely delta amongst themselves in any direction.
That's always the case within a pack, but only for REF_DELTA objects.
The OFS_DELTA objects have to be ordered. And yes, having deltas across
packs is disallowed to avoid cycles and to keep the database robust.
The only exception is for thin packs, but those are never created on
disk. Thin packs are only used for transport and quickly "fixed" upon
reception by appending the missing objects to them so they are not
"thin" anymore.
> What did you think about the bundle slicing stuff?
If I didn't comment on it already, then I probably missed it and have no
idea.
Nicolas
^ permalink raw reply
* Re: [PATCH JGIT] Ensure created test repositories use canonical paths
From: Jonas Fonseca @ 2009-08-22 3:32 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: Shawn O. Pearce, git
In-Reply-To: <200908210035.10825.robin.rosenberg.lists@dewire.com>
[With correct CC list. Sorry for the resend Robin]
On Thu, Aug 20, 2009 at 18:35, Robin
Rosenberg<robin.rosenberg.lists@dewire.com> wrote:
> onsdag 19 augusti 2009 15:18:11 skrev Jonas Fonseca <fonseca@diku.dk>:
>> Fixes breakage in the RepositoryCacheTest when running tests using:
>>
>> mvn -f ./jgit-maven/jgit/pom.xml test
>> [...]
>> @@ -217,7 +217,7 @@ public void setUp() throws Exception {
>> trash = new File(trashParent,"trash"+System.currentTimeMillis()+"."+(testcount++));
>> - trash_git = new File(trash, ".git");
>> + trash_git = new File(trash, ".git").getCanonicalFile();
>> @@ -307,7 +307,7 @@ protected Repository createNewEmptyRepo() throws IOException {
>> protected Repository createNewEmptyRepo(boolean bare) throws IOException {
>> final File newTestRepo = new File(trashParent, "new"
>> + System.currentTimeMillis() + "." + (testcount++)
>> - + (bare ? "" : "/") + ".git");
>> + + (bare ? "" : "/") + ".git").getCanonicalFile();
>
> We use getCanonicalFile here and Repository.gitDir is initialized with getAbsoluteDir.
BTW, a simpler fix would be to initialize trashParent to a canonical
path, which might be less intrusive.
> Does this work on all platforms?
I have only tested on Linux.
> Seems linux normalized things when you do things like, but I'm not sure that happens everywhere.
If you think it is a problem, let's drop the patch. It just seemed
like a simple way to increase robustness.
--
Jonas Fonseca
^ permalink raw reply
* How to recover from "reset --hard"
From: Ping Yin @ 2009-08-22 2:53 UTC (permalink / raw)
To: git mailing list
After adding a file to index, i do a "reset --hard", then how do i
recovery the file?
I want write all lost files to a directory and find it according to
the file size.
Does "git fsck --lost-found" write this file to .git\lost-found\other ?
Ping Yin
^ permalink raw reply
* Re: git diffall, open all diff files immediatly (eg tabbed window?in BC)
From: Seba Illingworth @ 2009-08-22 2:10 UTC (permalink / raw)
To: git
In-Reply-To: <20090821234512.GA58248@gmail.com>
David Aguilar <davvid <at> gmail.com> writes:
> I would recommend against saying 'git difftool head' on your
> blog beause that only works on OSX with its case-preserving yet
> case-insensitive filesystem....
Thanks David, understood and updated to 'HEAD'. 'head' had worked for me with my
sloppy Windows ways ;)
I struggled with your previous suggestion for handling paths with spaces;
I couldn't get the for-loop to split the input into individual filenames
on the line-break separator (after outer quotes expanded the result?).
But rewriting it this way seems to work well and handles spaces (Windows):
git diff --name-only "$@" | while read filename; do
git difftool "$@" --no-prompt "$filename" &
done
Hope you can comment on this variation?
And thanks for all the tips! Seba
^ 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