* Re: Workflow question
From: Andreas Ericsson @ 2007-09-25 19:09 UTC (permalink / raw)
To: Russ Brown; +Cc: git
In-Reply-To: <46F93A99.5080707@gmail.com>
Russ Brown wrote:
> Hi,
>
> I've been trying to think of a git workflow that we could use to replace
> our current svn/svk setup without simply using git in exactly the same
> way that we use svn/svk.
>
> Basically, we develop, maintain and enhance a website. On the central
> repo is trunk which represents live, and any number of project branches.
> Developers don't use local branches: they check out the project branches
> they're working on and commit to those. Developers merge from trunk to
> project branch from time to time to keep them current, and when a
> project rolls out the branch is merged to trunk.
>
> In addition to the obvious advantages that git would give us (such as
> properly tracking that code author as opposed to the person who did the
> merge), I'm wanting to gain the following benefits:
>
> * The repository is very large (multiple gigabytes) and mirroring using
> svk obviously takes a lot of time and space, so I'm keen to bring that
> down, most likely by the developer not needing to mirror branches he
> doesn't care about, or by being able to throw away branches he's done with.
> * The repository is full of revisions that fail review (or break
> things) and are fixed by subsequent revisions. We'd much rather be able
> to have the developer fix his revisions before they get committed
> 'upstream' (whatever that ends up meaning).
>
> I asked earlier about the email-based model that git itself uses, and
> while it appears to work very well for a widely-dispersed open-source
> project, I think it will be too cumbersome and slow for a fast-paced
> internal development team who make a number of live releases every day.
>
We came to the same conclusion at our workplace. Email works great, but
it's faster and better to just walk over to your colleague and ask what
he/she thinks about something.
> So, I've been thinking and have come up with this, which I'd appreciate
> comments about:
>
> 1. On a server we stick a git repository which contains the master
> branch, which represents what trunk did (i.e. the live platform). This
> branch contains the full history for the live platform.
A must-have for any more-than-two-developers setup, so so far so good ;-)
> 2. On the same server we clone that repo to create a second repository
> which is the developer area. In this we track master from the live repo,
> and also create project branches.
This isn't necessary. Branches in git are very nearly zero-cost, so having
them in the same repo as the master branch won't hurt a bit. You can add
an update-hook on the mothership repo to restrict access to the master
branch if you like, but creating two separate repos will likely give
more headache than it's worth.
> 3. Developers clone this developer repo, but I'd like them to be able
> to decide which branches they actually want to clone from that
> repository rather than simply cloning them all. Is this possible?
Yes, although I'd actually recommend you to clone the full repo anyway.
Since the various branches are likely to share quite a lot of history
the added overhead of a few extra branches will most likely be negligible.
git makes even very large codebases appear small and unobtrusive. The
linux kernel history since 2.6.12 contains 554853 objects and compresses
down to 178MiB.
I think KDE is the largest repo imported to git so far. I've forgotten
the exact numbers, but everyone was very impressed, and quite surprised,
at the vast difference between SVN and git storage requirements.
> 4. Developers create a local branch of the project they
> are working on and commit to that.
> 5. Once they think they're done, they publish their branch to the
> development repo and request for comments.
Using topic-branches is a much better strategy, usually, since that
allows each feature to be evaluated and improved on on its own, rather
than having to merge *all* of a particular developers changes just to
get desirable feature X. Note that cherry-pick provides ways of doing
that anyways, but in a much less elegant way, and your integrator/
release engineer will likely tear his hair out on a daily basis without
topic branches.
> 6. If all is not well, the developer creates a new local branch and
> moves good revisions from his previous one to the new one, modifying
> things as he goes, and republishes his new branch.
> 7. If all is well, their works gets merged or rebased onto the main
> project branch, and once that's ready it gets pushed to the master and
> rolled to live. The developer's individual branches get deleted from the
> dev repo since they're no longer required.
Topic branches would work the same, basically, except they can be pushed up
for review a lot faster.
If all the pushing gets cumbersome, it also makes it easy to send the patches
out as emails for discussion. It's usually easier to let git handle the
actual code transmissions, but discussing patches in emails works quite
well if it's intended for a wider audience.
> 8. From time to time the master branch gets merged to the project
> branches. Developer's local branches can be rebased against the project
> branch as they please.
>
criss-cross merging can turn kinda nasty though, as you may have a hard time
finding *the* common point when you run into that rogue merge with conflict
markers everywhere (it happens for everyone sooner or later).
I'd suggest you rebase the developer/topic branches onto master with regular
intervals instead.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: diffcore-rename performance mode
From: Jeff King @ 2007-09-25 19:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <20070925163843.GA22987@coredump.intra.peff.net>
On Tue, Sep 25, 2007 at 12:38:43PM -0400, Jeff King wrote:
>[...]
>
> What is most confusing is why the 'somefree' case performs so badly,
> since we should just be using the cnt_data. I'll see if gprof can shed
OK, I found the problem. estimate_similarity calls
diff_populate_filespec each time, even if we already have the cnt_data,
which leads to recomputing the blob contents from deltas. Oops.
Fixing this, the correct numbers are:
| stock | nofree | old somefree | fixed somefree
-----------------|-----------------------------------------------
user time (s) | 76.78 | 16.96 | 46.26 | 16.99
peak memory (Kb) | 52300 | 66796 | 59156 | 57328
So now we're at a 4.5x speedup for about 10% extra memory usage. Patch
will follow.
-Peff
^ permalink raw reply
* Re: [PATCH] resend: really plug memory leaks in git-svnimport
From: Andreas Ericsson @ 2007-09-25 18:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Stefan Sperling, git
In-Reply-To: <7vr6km6354.fsf@gitster.siamese.dyndns.org>
Junio C Hamano wrote:
> Stefan Sperling <stsp@elego.de> writes:
>
>> Junio asked me to resend this patch to the mailing list.
>>
>> This version of the patch is adjusted to apply cleanly
>> to current HEAD.
>>
>> @Junio: I'm not resending the multiple branch/tag dirs patch
>> just yet, because I want to polish it first -- I've got another
>> idea how to improve it.
>
> Ok.
>
> People on the list who still use git-svnimport, could you help
> with testing this patch? Will queue for 'pu' in the meantime.
>
I used to use it, but I've given up on it in favour of git svn.
Partly because git-svn seems to get cases right that git-svnimport
didn't, but mostly because it remembers where I fetched from, which
is damn handy.
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* Re: [PATCH] resend: really plug memory leaks in git-svnimport
From: Junio C Hamano @ 2007-09-25 17:55 UTC (permalink / raw)
To: Stefan Sperling; +Cc: git
In-Reply-To: <20070924105740.GB8900@ted>
Stefan Sperling <stsp@elego.de> writes:
> Junio asked me to resend this patch to the mailing list.
>
> This version of the patch is adjusted to apply cleanly
> to current HEAD.
>
> @Junio: I'm not resending the multiple branch/tag dirs patch
> just yet, because I want to polish it first -- I've got another
> idea how to improve it.
Ok.
People on the list who still use git-svnimport, could you help
with testing this patch? Will queue for 'pu' in the meantime.
^ permalink raw reply
* Workflow question
From: Russ Brown @ 2007-09-25 16:43 UTC (permalink / raw)
To: git
Hi,
I've been trying to think of a git workflow that we could use to replace
our current svn/svk setup without simply using git in exactly the same
way that we use svn/svk.
Basically, we develop, maintain and enhance a website. On the central
repo is trunk which represents live, and any number of project branches.
Developers don't use local branches: they check out the project branches
they're working on and commit to those. Developers merge from trunk to
project branch from time to time to keep them current, and when a
project rolls out the branch is merged to trunk.
In addition to the obvious advantages that git would give us (such as
properly tracking that code author as opposed to the person who did the
merge), I'm wanting to gain the following benefits:
* The repository is very large (multiple gigabytes) and mirroring using
svk obviously takes a lot of time and space, so I'm keen to bring that
down, most likely by the developer not needing to mirror branches he
doesn't care about, or by being able to throw away branches he's done with.
* The repository is full of revisions that fail review (or break
things) and are fixed by subsequent revisions. We'd much rather be able
to have the developer fix his revisions before they get committed
'upstream' (whatever that ends up meaning).
I asked earlier about the email-based model that git itself uses, and
while it appears to work very well for a widely-dispersed open-source
project, I think it will be too cumbersome and slow for a fast-paced
internal development team who make a number of live releases every day.
So, I've been thinking and have come up with this, which I'd appreciate
comments about:
1. On a server we stick a git repository which contains the master
branch, which represents what trunk did (i.e. the live platform). This
branch contains the full history for the live platform.
2. On the same server we clone that repo to create a second repository
which is the developer area. In this we track master from the live repo,
and also create project branches.
3. Developers clone this developer repo, but I'd like them to be able
to decide which branches they actually want to clone from that
repository rather than simply cloning them all. Is this possible?
4. Developers create a local branch of the project they
are working on and commit to that.
5. Once they think they're done, they publish their branch to the
development repo and request for comments.
6. If all is not well, the developer creates a new local branch and
moves good revisions from his previous one to the new one, modifying
things as he goes, and republishes his new branch.
7. If all is well, their works gets merged or rebased onto the main
project branch, and once that's ready it gets pushed to the master and
rolled to live. The developer's individual branches get deleted from the
dev repo since they're no longer required.
8. From time to time the master branch gets merged to the project
branches. Developer's local branches can be rebased against the project
branch as they please.
Firstly, is all of this possible, and if so would it be considered a
good way of going about it?
Any comments appreciated.
--
Russ
^ permalink raw reply
* Re: [PATCH] post-checkout hook, and related docs and tests
From: Josh England @ 2007-09-25 16:41 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfy138vql.fsf@gitster.siamese.dyndns.org>
On Mon, 2007-09-24 at 16:54 -0700, Junio C Hamano wrote:
> "Josh England" <jjengla@sandia.gov> writes:
>
> > On Mon, 2007-09-24 at 14:07 -0700, Junio C Hamano wrote:
> > ...
> >> If you want to spacial case
> >>
> >> $ git checkout otherbranch path.c
> >>
> >> it raises another issue. Which commit should supply the
> >> "extended attribute description" for path.c? Should it be taken
> >> from the current commit (aka HEAD), otherbranch, or the index?
> >
> > This already is a special case and your question is valid but not one
> > that git should necessary care about. Since extended attributes are not
> > built into git the only way to handle them is through hooks. A such, it
> > is up to the hook to worry about these kinds of issues.
>
> The fear I have is that that kind of thinking would necessitate
> your hook to be called after the user edits paths.c in any other
> way not to confuse users.
>
> What I am questioning is where we should stop, in order to keep
> things simpler to explain, and I happen to think that it is far
> easier if we can teach that "git checkout other path.c" is
> equivalent to "git cat-file blob other:path.c >path.c" followed
> by "git add path.c", than saying "checkout is magical and if you
> have external hook it can do far more than editing the file
> yourself to arrive at the same contents".
>
> But I am obviously not the one who is interested in tracking
> extended attributes attached to git contents, and I do not feel
> too strongly about one way or the other. I am Ok with it if you
> think "checkout is magical" is easier to teach [*1*].
>
> I just wanted to make sure we know what semantics this is
> bringing in, and get it clearly documented. That's all.
OK. I'll try to come up with some good wording for the documentation.
So this leads to my next question: Should the post-merge patch be
brought in under this same umbrella to form a single post-checkout hook,
or should it stay a separate hook?
-JE
^ permalink raw reply
* Re: diffcore-rename performance mode
From: Jeff King @ 2007-09-25 16:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Linus Torvalds, git
In-Reply-To: <20070918085413.GA11751@coredump.intra.peff.net>
On Tue, Sep 18, 2007 at 04:54:13AM -0400, Jeff King wrote:
> > > However, keeping around _just_ the
> > > cnt_data caused only about 100M of extra memory consumption (and gave
> > > the same performance boost).
> >
> > That would be an interesting and relatively low-hanging optimization.
>
> I can produce memory usage numbers for the kernel, too.
And here are some kernel numbers. I measured performance of this script
in the linux-2.6 repository:
#!/bin/sh
last=
git-tag | grep -v -- - | while read tag; do
if test -n "$last"; then
echo Diffing $last..$tag
git-diff --raw -M -l0 $last $tag >/dev/null
fi
last=$tag
done
under the assumption that diffing between major revisions would give a
good medium of diffs that would be large enough to show the n^2 rename
behavior, but still small enough to be close to "everyday" usage.
I measured three different approaches:
1. stock 'next' (stock)
2. removing entirely the calls to diff_free_filespec_data (nofree)
3. changing those free calls to free everything except cnt_data (somefree)
And I measured two things:
1. user CPU time to complete
2. peak memory usage
All numbers are warm-cache, and typical cases after multiple runs.
| stock | nofree | somefree
-----------------|---------------------------
user time (s) | 76.78 | 16.96 | 46.26
peak memory (Kb) | 52300 | 66796 | 59156
The raw 'time' output is below:
stock:
76.78user 3.35system 1:20.72elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+166733minor)pagefaults 0swaps
nofree:
16.96user 1.46system 0:18.47elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+185353minor)pagefaults 0swaps
somefree:
46.26user 1.54system 0:47.94elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+178819minor)pagefaults 0swaps
So this is definitely worth pursuing, as it yields massive speedups even
for regular repositories. And even the 'nofree' case only costs us 14M
of extra memory (although it is a 27% increase, this just isn't that
memory-hungry an endeavour for the sizes of changes we're talking
about). And as Linus noted, now that we have a default rename limit,
you're not likely to hit an explosion of memory usage.
What is most confusing is why the 'somefree' case performs so badly,
since we should just be using the cnt_data. I'll see if gprof can shed
any light on that. It would be nice to use it instead, since it will
have much better memory usage in the face of large blobs (e.g., my
pathological case that started this whole thread).
-Peff
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: David Kastrup @ 2007-09-25 16:04 UTC (permalink / raw)
To: git
In-Reply-To: <46F92F26.6050204@viscovery.net>
Johannes Sixt <j.sixt@viscovery.net> writes:
> David Kastrup schrieb:
>> Johannes Sixt <j.sixt@viscovery.net> writes:
>>> I poked around a bit, but one major obstacle is that the assignments
>>> in $author_script are on separate lines, which you would have to
>>> splice into a single line before you can insert them in the eval.
>>
>> Hm? Why? Newlines separate assignments just as reliable as spaces
>> do. They are primarily special to the tty as line separators, not the
>> shell as such.
>
> The task here is to have the assignments on the same line as the
> command at the end so that they are locally exported. Here we are
> inside an 'eval', and the new-lines *do* what their name suggest: make
> new lines.
The documentation to eval clearly states:
`eval'
eval [ARGUMENTS]
The arguments are concatenated together into a single command,
which is then read and executed, and its exit status returned as
the exit status of `eval'. If there are no arguments or only
empty arguments, the return status is zero.
So we are talking about a single command here. However, we indeed get
$ eval "echo x
> y
> z"
x
bash: y: command not found
bash: z: command not found
$
Um, so I have been talking nonsense. Does "the docs made me do it"
count as excuse?
--
David Kastrup
^ permalink raw reply
* Re: [PATCH] user-manual: Explain what submodules are good for.
From: J. Bruce Fields @ 2007-09-25 16:09 UTC (permalink / raw)
To: Michael Smith; +Cc: Miklos Vajna, git
In-Reply-To: <1190724278-8586-1-git-send-email-msmith@cbnco.com>
On Tue, Sep 25, 2007 at 08:44:38AM -0400, Michael Smith wrote:
> Rework the introduction to the Submodules section to explain why
> someone would use them, and fix up submodule references from the
> tree-object and todo sections.
Looks good to me; thanks!
Acked-by: J. Bruce Fields <bfields@citi.umich.edu>
--b.
> Signed-off-by: Michael Smith <msmith@cbnco.com>
> ---
> Documentation/user-manual.txt | 54 +++++++++++++++++++++++++++++++---------
> 1 files changed, 42 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
> index a085ca1..c7fdf25 100644
> --- a/Documentation/user-manual.txt
> +++ b/Documentation/user-manual.txt
> @@ -2856,8 +2856,7 @@ between two related tree objects, since it can ignore any entries with
> identical object names.
>
> (Note: in the presence of submodules, trees may also have commits as
> -entries. See gitlink:git-submodule[1] and gitlink:gitmodules.txt[1]
> -for partial documentation.)
> +entries. See <<submodules>> for documentation.)
>
> Note that the files all have mode 644 or 755: git actually only pays
> attention to the executable bit.
> @@ -3163,12 +3162,45 @@ information as long as you have the name of the tree that it described.
> Submodules
> ==========
>
> -This tutorial explains how to create and publish a repository with submodules
> -using the gitlink:git-submodule[1] command.
> -
> -Submodules maintain their own identity; the submodule support just stores the
> -submodule repository location and commit ID, so other developers who clone the
> -superproject can easily clone all the submodules at the same revision.
> +Large projects are often composed of smaller, self-contained modules. For
> +example, an embedded Linux distribution's source tree would include every
> +piece of software in the distribution with some local modifications; a movie
> +player might need to build against a specific, known-working version of a
> +decompression library; several independent programs might all share the same
> +build scripts.
> +
> +With centralized revision control systems this is often accomplished by
> +including every module in one single repository. Developers can check out
> +all modules or only the modules they need to work with. They can even modify
> +files across several modules in a single commit while moving things around
> +or updating APIs and translations.
> +
> +Git does not allow partial checkouts, so duplicating this approach in Git
> +would force developers to keep a local copy of modules they are not
> +interested in touching. Commits in an enormous checkout would be slower
> +than you'd expect as Git would have to scan every directory for changes.
> +If modules have a lot of local history, clones would take forever.
> +
> +On the plus side, distributed revision control systems can much better
> +integrate with external sources. In a centralized model, a single arbitrary
> +snapshot of the external project is exported from its own revision control
> +and then imported into the local revision control on a vendor branch. All
> +the history is hidden. With distributed revision control you can clone the
> +entire external history and much more easily follow development and re-merge
> +local changes.
> +
> +Git's submodule support allows a repository to contain, as a subdirectory, a
> +checkout of an external project. Submodules maintain their own identity;
> +the submodule support just stores the submodule repository location and
> +commit ID, so other developers who clone the containing project
> +("superproject") can easily clone all the submodules at the same revision.
> +Partial checkouts of the superproject are possible: you can tell Git to
> +clone none, some or all of the submodules.
> +
> +The gitlink:git-submodule[1] command is available since Git 1.5.3. Users
> +with Git 1.5.2 can look up the submodule commits in the repository and
> +manually check them out; earlier versions won't recognize the submodules at
> +all.
>
> To see how submodule support works, create (for example) four example
> repositories that can be used later as a submodule:
> @@ -3213,8 +3245,8 @@ The `git submodule add` command does a couple of things:
>
> - It clones the submodule under the current directory and by default checks out
> the master branch.
> -- It adds the submodule's clone path to the `.gitmodules` file and adds this
> - file to the index, ready to be committed.
> +- It adds the submodule's clone path to the gitlink:gitmodules[5] file and
> + adds this file to the index, ready to be committed.
> - It adds the submodule's current commit ID to the index, ready to be
> committed.
>
> @@ -4277,5 +4309,3 @@ Write a chapter on using plumbing and writing scripts.
> Alternates, clone -reference, etc.
>
> git unpack-objects -r for recovery
> -
> -submodules
> --
> 1.5.3
>
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: Johannes Sixt @ 2007-09-25 15:54 UTC (permalink / raw)
To: David Kastrup; +Cc: git, Johannes Schindelin
In-Reply-To: <86ve9y6bvm.fsf@lola.quinscape.zz>
David Kastrup schrieb:
> Johannes Sixt <j.sixt@viscovery.net> writes:
>> I poked around a bit, but one major obstacle is that the assignments
>> in $author_script are on separate lines, which you would have to
>> splice into a single line before you can insert them in the eval.
>
> Hm? Why? Newlines separate assignments just as reliable as spaces
> do. They are primarily special to the tty as line separators, not the
> shell as such.
The task here is to have the assignments on the same line as the command at
the end so that they are locally exported. Here we are inside an 'eval', and
the new-lines *do* what their name suggest: make new lines.
-- Hannes
^ permalink raw reply
* [PATCH 5/5] rebase -i: avoid exporting GIT_AUTHOR_* variables
From: Johannes Schindelin @ 2007-09-25 15:43 UTC (permalink / raw)
To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0709251640360.28395@racer.site>
It is somewhat unsafe to export the GIT_AUTHOR_* variables, since a later
call to git-commit or git-merge could pick them up inadvertently.
So avoid the export, using a recipe provided by Johannes Sixt.
Incidentally, this fixes authorship of merges with "rebase --preserve -i".
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
git-rebase--interactive.sh | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 445a299..e3e89dd 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -174,7 +174,11 @@ pick_one_preserving_merges () {
eval "$author_script"
msg="$(git cat-file commit $sha1 | sed -e '1,/^$/d')"
# NEEDSWORK: give rerere a chance
- if ! output git merge $STRATEGY -m "$msg" $new_parents
+ if ! GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
+ GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
+ GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
+ output git merge $STRATEGY -m "$msg" \
+ $new_parents
then
printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
die Error redoing merge $sha1
@@ -281,7 +285,9 @@ do_next () {
f)
# This is like --amend, but with a different message
eval "$author_script"
- export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+ GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
+ GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
+ GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
$USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
;;
t)
--
1.5.3.2.1057.gf4dc1
^ permalink raw reply related
* [PATCH 4/5] rebase -i: work on a detached HEAD
From: Johannes Schindelin @ 2007-09-25 15:43 UTC (permalink / raw)
To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0709251640360.28395@racer.site>
Earlier, rebase -i refused to rebase a detached HEAD. Now it no longer
does.
Incidentally, this fixes "git gc --auto" shadowing the true exit status.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
git-rebase--interactive.sh | 23 +++++++++++++++--------
t/t3404-rebase-interactive.sh | 8 ++++++++
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 4f46a15..445a299 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -312,17 +312,20 @@ do_next () {
else
NEWHEAD=$(git rev-parse HEAD)
fi &&
- message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
- git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
- git symbolic-ref HEAD $HEADNAME && {
+ case $HEADNAME in
+ refs/*)
+ message="$GIT_REFLOG_ACTION: $HEADNAME onto $SHORTONTO)" &&
+ git update-ref -m "$message" $HEADNAME $NEWHEAD $OLDHEAD &&
+ git symbolic-ref HEAD $HEADNAME
+ ;;
+ esac && {
test ! -f "$DOTEST"/verbose ||
git diff --stat $(cat "$DOTEST"/head)..HEAD
} &&
rm -rf "$DOTEST" &&
+ git gc --auto &&
warn "Successfully rebased and updated $HEADNAME."
- git gc --auto
-
exit
}
@@ -362,7 +365,11 @@ do
HEADNAME=$(cat "$DOTEST"/head-name)
HEAD=$(cat "$DOTEST"/head)
- git symbolic-ref HEAD $HEADNAME &&
+ case $HEADNAME in
+ refs/*)
+ git symbolic-ref HEAD $HEADNAME
+ ;;
+ esac &&
output git reset --hard $HEAD &&
rm -rf "$DOTEST"
exit
@@ -439,8 +446,8 @@ do
test -z "$ONTO" && ONTO=$UPSTREAM
: > "$DOTEST"/interactive || die "Could not mark as interactive"
- git symbolic-ref HEAD > "$DOTEST"/head-name ||
- die "Could not get HEAD"
+ git symbolic-ref HEAD > "$DOTEST"/head-name 2> /dev/null ||
+ echo "detached HEAD" > "$DOTEST"/head-name
echo $HEAD > "$DOTEST"/head
echo $UPSTREAM > "$DOTEST"/upstream
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 1af73a4..f2214dd 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -309,4 +309,12 @@ test_expect_success '--continue tries to commit, even for "edit"' '
test $parent = $(git rev-parse HEAD^)
'
+test_expect_success 'rebase a detached HEAD' '
+ grandparent=$(git rev-parse HEAD~2) &&
+ git checkout $(git rev-parse HEAD) &&
+ test_tick &&
+ FAKE_LINES="2 1" git rebase -i HEAD~2 &&
+ test $grandparent = $(git rev-parse HEAD~2)
+'
+
test_done
--
1.5.3.2.1057.gf4dc1
^ permalink raw reply related
* [PATCH 3/5] rebase -i: Fix numbers in progress report
From: Johannes Schindelin @ 2007-09-25 15:43 UTC (permalink / raw)
To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0709251640360.28395@racer.site>
Instead of counting all lines in done and todo, we now count the actions
before outputting "$Rebasing ($count/$total)".
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
git-rebase--interactive.sh | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index c850411..4f46a15 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -72,8 +72,8 @@ mark_action_done () {
sed -e 1q < "$TODO" >> "$DONE"
sed -e 1d < "$TODO" >> "$TODO".new
mv -f "$TODO".new "$TODO"
- count=$(($(wc -l < "$DONE")))
- total=$(($count+$(wc -l < "$TODO")))
+ count=$(($(grep -ve '^$' -e '^#' < "$DONE" | wc -l)))
+ total=$(($count+$(grep -ve '^$' -e '^#' < "$TODO" | wc -l)))
printf "Rebasing (%d/%d)\r" $count $total
test -z "$VERBOSE" || echo
}
--
1.5.3.2.1057.gf4dc1
^ permalink raw reply related
* [PATCH 2/5] rebase -i: style fixes and minor cleanups
From: Johannes Schindelin @ 2007-09-25 15:42 UTC (permalink / raw)
To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0709251640360.28395@racer.site>
This patch indents ";;" consistently with the rest of git's shell scripts,
and makes sure that ";;" are before each "esac".
It introduces a helper function "has_action", to make it easier to read
the intentions of the code.
Errors from "git rev-parse --verify" are no longer ignored.
Spaces are quoted using single quotes instead of a backslash, for
readability.
A "test $preserve=f" (missing spaces) was fixed; hashes are no longer
written to "$DOTEST"/rewritten/ unnecessarily.
We used to quote the message for a squash, only to have "echo" unquote it.
Now we use "printf" and do not need to quote to start with.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
git-rebase--interactive.sh | 48 +++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 58f6f28..c850411 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -41,9 +41,10 @@ output () {
test $status != 0 &&
cat "$DOTEST"/output
return $status
- ;;
+ ;;
*)
"$@"
+ ;;
esac
}
@@ -63,6 +64,7 @@ comment_for_reflog () {
''|rebase*)
GIT_REFLOG_ACTION="rebase -i ($1)"
export GIT_REFLOG_ACTION
+ ;;
esac
}
@@ -96,13 +98,18 @@ die_abort () {
die "$1"
}
+has_action () {
+ grep -vqe '^$' -e '^#' "$1"
+}
+
pick_one () {
no_ff=
case "$1" in -n) sha1=$2; no_ff=t ;; *) sha1=$1 ;; esac
output git rev-parse --verify $sha1 || die "Invalid commit name: $sha1"
test -d "$REWRITTEN" &&
pick_one_preserving_merges "$@" && return
- parent_sha1=$(git rev-parse --verify $sha1^ 2>/dev/null)
+ parent_sha1=$(git rev-parse --verify $sha1^) ||
+ die "Could not get the parent of $sha1"
current_sha1=$(git rev-parse --verify HEAD)
if test $no_ff$current_sha1 = $parent_sha1; then
output git reset --hard $sha1
@@ -130,7 +137,7 @@ pick_one_preserving_merges () {
fast_forward=t
preserve=t
new_parents=
- for p in $(git rev-list --parents -1 $sha1 | cut -d\ -f2-)
+ for p in $(git rev-list --parents -1 $sha1 | cut -d' ' -f2-)
do
if test -f "$REWRITTEN"/$p
then
@@ -142,41 +149,43 @@ pick_one_preserving_merges () {
;; # do nothing; that parent is already there
*)
new_parents="$new_parents $new_p"
+ ;;
esac
fi
done
case $fast_forward in
t)
output warn "Fast forward to $sha1"
- test $preserve=f && echo $sha1 > "$REWRITTEN"/$sha1
+ test $preserve = f || echo $sha1 > "$REWRITTEN"/$sha1
;;
f)
test "a$1" = a-n && die "Refusing to squash a merge: $sha1"
- first_parent=$(expr "$new_parents" : " \([^ ]*\)")
+ first_parent=$(expr "$new_parents" : ' \([^ ]*\)')
# detach HEAD to current parent
output git checkout $first_parent 2> /dev/null ||
die "Cannot move HEAD to $first_parent"
echo $sha1 > "$DOTEST"/current-commit
case "$new_parents" in
- \ *\ *)
+ ' '*' '*)
# redo merge
author_script=$(get_author_ident_from_commit $sha1)
eval "$author_script"
- msg="$(git cat-file commit $sha1 | \
- sed -e '1,/^$/d' -e "s/[\"\\]/\\\\&/g")"
+ msg="$(git cat-file commit $sha1 | sed -e '1,/^$/d')"
# NEEDSWORK: give rerere a chance
if ! output git merge $STRATEGY -m "$msg" $new_parents
then
- echo "$msg" > "$GIT_DIR"/MERGE_MSG
+ printf "%s\n" "$msg" > "$GIT_DIR"/MERGE_MSG
die Error redoing merge $sha1
fi
;;
*)
output git cherry-pick $STRATEGY "$@" ||
die_with_patch $sha1 "Could not pick $sha1"
+ ;;
esac
+ ;;
esac
}
@@ -213,12 +222,11 @@ peek_next_command () {
}
do_next () {
- test -f "$DOTEST"/message && rm "$DOTEST"/message
- test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
- test -f "$DOTEST"/amend && rm "$DOTEST"/amend
+ rm -f "$DOTEST"/message "$DOTEST"/author-script \
+ "$DOTEST"/amend || exit
read command sha1 rest < "$TODO"
case "$command" in
- \#|'')
+ '#'*|'')
mark_action_done
;;
pick)
@@ -246,7 +254,7 @@ do_next () {
squash)
comment_for_reflog squash
- test -z "$(grep -ve '^$' -e '^#' < $DONE)" &&
+ has_action "$DONE" ||
die "Cannot 'squash' without a previous commit"
mark_action_done
@@ -256,11 +264,12 @@ do_next () {
EDIT_COMMIT=
USE_OUTPUT=output
cp "$MSG" "$SQUASH_MSG"
- ;;
+ ;;
*)
EDIT_COMMIT=-e
USE_OUTPUT=
- test -f "$SQUASH_MSG" && rm "$SQUASH_MSG"
+ rm -f "$SQUASH_MSG" || exit
+ ;;
esac
failed=f
@@ -280,11 +289,13 @@ do_next () {
warn
warn "Could not apply $sha1... $rest"
die_with_patch $sha1 ""
+ ;;
esac
;;
*)
warn "Unknown command: $command $sha1 $rest"
die_with_patch $sha1 "Please fix this in the file $TODO."
+ ;;
esac
test -s "$TODO" && return
@@ -475,17 +486,18 @@ EOF
$UPSTREAM...$HEAD | \
sed -n "s/^>/pick /p" >> "$TODO"
- test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
+ has_action "$TODO" ||
die_abort "Nothing to do"
cp "$TODO" "$TODO".backup
git_editor "$TODO" ||
die "Could not execute editor"
- test -z "$(grep -ve '^$' -e '^#' < $TODO)" &&
+ has_action "$TODO" ||
die_abort "Nothing to do"
output git checkout $ONTO && do_rest
+ ;;
esac
shift
done
--
1.5.3.2.1057.gf4dc1
^ permalink raw reply related
* [PATCH 1/5] rebase -i: commit when continuing after "edit"
From: Johannes Schindelin @ 2007-09-25 15:42 UTC (permalink / raw)
To: git, gitster
In-Reply-To: <Pine.LNX.4.64.0709251640360.28395@racer.site>
When doing an "edit" on a commit, editing and git-adding some files,
"git rebase -i" complained about a missing "author-script". The idea was
that the user would call "git commit --amend" herself.
But we can be nice and do that for the user.
Noticed by Dmitry Potapov.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
git-rebase--interactive.sh | 17 +++++++++++------
t/t3404-rebase-interactive.sh | 14 +++++++++++++-
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index d2983d1..58f6f28 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -77,15 +77,16 @@ mark_action_done () {
}
make_patch () {
- parent_sha1=$(git rev-parse --verify "$1"^ 2> /dev/null)
+ parent_sha1=$(git rev-parse --verify "$1"^) ||
+ die "Cannot get patch for $1^"
git diff "$parent_sha1".."$1" > "$DOTEST"/patch
+ test -f "$DOTEST"/message ||
+ git cat-file commit "$1" | sed "1,/^$/d" > "$DOTEST"/message
+ test -f "$DOTEST"/author-script ||
+ get_author_ident_from_commit "$1" > "$DOTEST"/author-script
}
die_with_patch () {
- test -f "$DOTEST"/message ||
- git cat-file commit $sha1 | sed "1,/^$/d" > "$DOTEST"/message
- test -f "$DOTEST"/author-script ||
- get_author_ident_from_commit $sha1 > "$DOTEST"/author-script
make_patch "$1"
die "$2"
}
@@ -214,6 +215,7 @@ peek_next_command () {
do_next () {
test -f "$DOTEST"/message && rm "$DOTEST"/message
test -f "$DOTEST"/author-script && rm "$DOTEST"/author-script
+ test -f "$DOTEST"/amend && rm "$DOTEST"/amend
read command sha1 rest < "$TODO"
case "$command" in
\#|'')
@@ -233,6 +235,7 @@ do_next () {
pick_one $sha1 ||
die_with_patch $sha1 "Could not apply $sha1... $rest"
make_patch $sha1
+ : > "$DOTEST"/amend
warn
warn "You can amend the commit now, with"
warn
@@ -332,7 +335,9 @@ do
git update-index --refresh &&
git diff-files --quiet &&
! git diff-index --cached --quiet HEAD &&
- . "$DOTEST"/author-script &&
+ . "$DOTEST"/author-script && {
+ test ! -f "$DOTEST"/amend || git reset --soft HEAD^
+ } &&
export GIT_AUTHOR_NAME GIT_AUTHOR_NAME GIT_AUTHOR_DATE &&
git commit -F "$DOTEST"/message -e
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 718c9c1..1af73a4 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -80,7 +80,7 @@ cat "$1".tmp
action=pick
for line in $FAKE_LINES; do
case $line in
- squash)
+ squash|edit)
action="$line";;
*)
echo sed -n "${line}s/^pick/$action/p"
@@ -297,4 +297,16 @@ test_expect_success 'ignore patch if in upstream' '
test $HEAD = $(git rev-parse HEAD^)
'
+test_expect_success '--continue tries to commit, even for "edit"' '
+ parent=$(git rev-parse HEAD^) &&
+ test_tick &&
+ FAKE_LINES="edit 1" git rebase -i HEAD^ &&
+ echo edited > file7 &&
+ git add file7 &&
+ FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue &&
+ test edited = $(git show HEAD:file7) &&
+ git show HEAD | grep chouette &&
+ test $parent = $(git rev-parse HEAD^)
+'
+
test_done
--
1.5.3.2.1057.gf4dc1
^ permalink raw reply related
* [PATCH 0/5] Two real fixes, two minor fixes, and a style fix
From: Johannes Schindelin @ 2007-09-25 15:42 UTC (permalink / raw)
To: git, gitster
Hi,
this patch series arose out of the comments to the simple fix I sent out
earlier, which has now become the first patch of the series.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: Johannes Schindelin @ 2007-09-25 15:16 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Junio C Hamano, Dmitry Potapov, git
In-Reply-To: <46F922E0.80504@viscovery.net>
Hi,
On Tue, 25 Sep 2007, Johannes Sixt wrote:
> Johannes Schindelin schrieb:
>
> > On Tue, 25 Sep 2007, Johannes Sixt wrote:
> >
> > > Johannes Schindelin schrieb:
> > >
> > > > On Tue, 25 Sep 2007, Johannes Sixt wrote:
> > > > > How about:
> > > > >
> > > > > eval "$author_script"
> > > > > GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
> > > > > GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
> > > > > GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
> > > > > $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
> > > > >
> > > > > and if you dislike that, put the two questionable lines in
> > > > > parenthesis.
> > > >
> > > > That looks ugly. I'd rather have something like
> > > >
> > > > eval "$USE_OUTPUT $author_script git commit -F \"$MSG\" $EDIT_COMMIT"
> > > >
> > > > but I'm not quite certain if that is enough, what with the funny
> > > > characters people put into path names these days ($MSG points to
> > > > "$DOTEST"/message).
> > >
> > > I, too, find it ugly, but I think it's the most readable way to do
> > > it. Your version is certainly underquoted.
> > >
> > > I poked around a bit, but one major obstacle is that the assignments
> > > in $author_script are on separate lines, which you would have to
> > > splice into a single line before you can insert them in the eval.
> >
> > But is your version not underquoted, too? For example, if the author
> > name is, say 'Johannes "Dscho" Schindelin', would your version still
> > get the \" in the name?
>
> No, it's not underquoted; yes, it would still get the \" in the name.
> The shell parses the assignments
>
> GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME"
>
> only once; it does not parse it again after the dq'd string was expanded.
Ah, okay. I'll go with your version then.
Ciao,
Dscho
^ permalink raw reply
* Re: Q: howto rebase
From: Jeff King @ 2007-09-25 15:02 UTC (permalink / raw)
To: lode leroy; +Cc: git
In-Reply-To: <BAY105-F33DC84FACB8B66BFEB9EC8FFB70@phx.gbl>
On Tue, Sep 25, 2007 at 04:46:59PM +0200, lode leroy wrote:
> In "version B" I introduce the "fix c", but in "version D" I realize it
> should have
> been in some other place. (commit D moves the fix to its proper place).
> A-B-C-D-E
>
> Now I want to 'rewrite history'.
> I would like to move commit D after B
> A-B-D'-C'-E
>
> and then fold the commits B and D' into a single commit.
> A-B'-C'-E
>
> I somehow managed to get this done using "rebase -i"
> by exchanging the 2 appropriate lines, and then deleting the second one,
> but I'd like to understand how to do this from the command line...
The essence of git rebase is "move these commits as if they had happened
off of a different base commit." The interactive mode of rebase is
considerably more powerful, in that it allows squashing, deleting, and
arbitrary reordering. To do solve your problem without using "rebase
-i", you could do this:
# make a new branch based on 'B', which is where we want to base our commits
git-checkout -b tmp B
# pick the changes from 'D', but don't commit
git-cherry-pick -n D
# redo 'B' with the new changes
git-commit --amend
now you have a graph like this:
A-B-C-D-E
\
\-B' <-- branch tip
so you need to rebase C-D-E on top of it (and rebase will realize that
'D' has already been applied), with:
git-rebase --onto tmp B master
Converting this to the manpage terminology, "B" is your upstream, and
you want to grab all of the changes from "B" to your "master", but you
want to put them on the newly created B'. Which perhaps is a little
confusing, but that's because git-rebase was designed for a simpler
situation: you and some upstream repo both made commits that the other
doesn't have, and you want to pretend your work is based off of their
most recent version.
You can see that "rebase -i" is a lot more flexible for these sorts of
history re-writing schemes. If you really must do it without user
interaction, I suspect you could use a sed script as your $GIT_EDITOR.
-Peff
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: Johannes Sixt @ 2007-09-25 15:01 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Dmitry Potapov, git
In-Reply-To: <Pine.LNX.4.64.0709251528560.28395@racer.site>
Johannes Schindelin schrieb:
> Hi,
>
> On Tue, 25 Sep 2007, Johannes Sixt wrote:
>
>> Johannes Schindelin schrieb:
>>
>>> On Tue, 25 Sep 2007, Johannes Sixt wrote:
>>>> How about:
>>>>
>>>> eval "$author_script"
>>>> GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
>>>> GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
>>>> GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
>>>> $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
>>>>
>>>> and if you dislike that, put the two questionable lines in parenthesis.
>>> That looks ugly. I'd rather have something like
>>>
>>> eval "$USE_OUTPUT $author_script git commit -F \"$MSG\" $EDIT_COMMIT"
>>>
>>> but I'm not quite certain if that is enough, what with the funny
>>> characters people put into path names these days ($MSG points to
>>> "$DOTEST"/message).
>> I, too, find it ugly, but I think it's the most readable way to do it.
>> Your version is certainly underquoted.
>>
>> I poked around a bit, but one major obstacle is that the assignments in
>> $author_script are on separate lines, which you would have to splice
>> into a single line before you can insert them in the eval.
>
> But is your version not underquoted, too? For example, if the author name
> is, say 'Johannes "Dscho" Schindelin', would your version still get the \"
> in the name?
No, it's not underquoted; yes, it would still get the \" in the name. The
shell parses the assignments
GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME"
only once; it does not parse it again after the dq'd string was expanded.
-- Hannes
^ permalink raw reply
* Re: [PATCH] rebase -i: commit when continuing after "edit"
From: David Kastrup @ 2007-09-25 14:46 UTC (permalink / raw)
To: git
In-Reply-To: <46F91879.6030301@viscovery.net>
Johannes Sixt <j.sixt@viscovery.net> writes:
> Johannes Schindelin schrieb:
>> Hi,
>>
>> On Tue, 25 Sep 2007, Johannes Sixt wrote:
>>> How about:
>>>
>>> eval "$author_script"
>>> GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME" \
>>> GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL" \
>>> GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE" \
>>> $USE_OUTPUT git commit -F "$MSG" $EDIT_COMMIT
>>>
>>> and if you dislike that, put the two questionable lines in parenthesis.
>>
>> That looks ugly. I'd rather have something like
>>
>> eval "$USE_OUTPUT $author_script git commit -F \"$MSG\" $EDIT_COMMIT"
>>
>> but I'm not quite certain if that is enough, what with the funny
>> characters people put into path names these days ($MSG points to
>> "$DOTEST"/message).
>
> I, too, find it ugly, but I think it's the most readable way to do
> it. Your version is certainly underquoted.
Proper quoting in my book would be
eval "$USE_OUTPUT $author_script git commit -F" '"$MSG"' "$EDIT_COMMIT"
(I am not sure I am correct about $EDIT_COMMIT, not having looked at
its definition).
Important is the double quotation of $MSG to keep it as a single argument.
> I poked around a bit, but one major obstacle is that the assignments
> in $author_script are on separate lines, which you would have to
> splice into a single line before you can insert them in the eval.
Hm? Why? Newlines separate assignments just as reliable as spaces
do. They are primarily special to the tty as line separators, not the
shell as such.
--
David Kastrup
^ permalink raw reply
* Re: Q: howto rebase
From: lode leroy @ 2007-09-25 14:54 UTC (permalink / raw)
To: git
In-Reply-To: <b41dbf4a0709250748l52b64155k65b6adb16e8dbcd5@mail.gmail.com>
I'm trying to understand how rebase works, but I need some help to get it.
Suppose I do the following workflow... (see below)
In "version B" I introduce the "fix c", but in "version D" I realize
it should have
been in some other place. (commit D moves the fix to its proper place).
A-B-C-D-E
Now I want to 'rewrite history'.
I would like to move commit D after B
A-B-D'-C'-E
and then fold the commits B and D' into a single commit.
A-B'-C'-E
I somehow managed to get this done using "rebase -i"
by exchanging the 2 appropriate lines, and then deleting the second one,
but I'd like to understand how to do this from the command line...
Could anyone enlighten me? I've read git-rebase(1) several times,
but don't seem to get it right...
cat > file <<EOF
a
b
d
e
g
h
EOF
git add file
git commit -m 'A' -a
cat > file <<EOF
a
b
d
e
g
c
h
EOF
git commit -m 'B' -a
cat > file <<EOF
a
b
d
e
f
g
c
h
EOF
git commit -m 'C' -a
cat > file <<EOF
a
b
c
d
e
f
g
h
EOF
git commit -m 'D' -a
cat > file <<EOF
a
b
c
d
e
f
g
h
i
EOF
git commit -m 'E' -a
^ permalink raw reply
* Re: Q: howto rebase
From: Johannes Schindelin @ 2007-09-25 14:49 UTC (permalink / raw)
To: lode leroy; +Cc: git
In-Reply-To: <BAY105-F33DC84FACB8B66BFEB9EC8FFB70@phx.gbl>
Hi,
On Tue, 25 Sep 2007, lode leroy wrote:
> I'm trying to understand how rebase works, but I need some help to get it.
> Suppose I do the following workflow... (see below)
>
> In "version B" I introduce the "fix c", but in "version D" I realize it
> should have
> been in some other place. (commit D moves the fix to its proper place).
> A-B-C-D-E
>
> Now I want to 'rewrite history'.
> I would like to move commit D after B
> A-B-D'-C'-E
>
> and then fold the commits B and D' into a single commit.
> A-B'-C'-E
>
> I somehow managed to get this done using "rebase -i"
> by exchanging the 2 appropriate lines, and then deleting the second one,
> but I'd like to understand how to do this from the command line...
Almost. Your "fold" is called "squash". So instead of deleting the
second one, you probably wanted to squash it.
Hth,
Dscho
^ permalink raw reply
* Re: [PATCH] Don't use "<unknown>" for unknown values of placeholders and suppress printing of empty user formats.
From: Johannes Schindelin @ 2007-09-25 14:47 UTC (permalink / raw)
To: Michal Vitecek; +Cc: git, Junio C Hamano
In-Reply-To: <20070925143846.GQ22869@mageo.cz>
Hi,
On Tue, 25 Sep 2007, Michal Vitecek wrote:
> ---
>
> Sending the patch again in correct form (hopefully) as instructed by
> Johannes Schindelin. Sorry for the hassle.
Thanks.
> diff --git a/commit.c b/commit.c
> index 99f65ce..c9a1818 100644
> --- a/commit.c
> +++ b/commit.c
> @@ -917,9 +917,6 @@ long format_commit_message(const struct commit *commit, const void *format,
> }
> if (msg[i])
> table[IBODY].value = xstrdup(msg + i);
> - for (i = 0; i < ARRAY_SIZE(table); i++)
> - if (!table[i].value)
> - interp_set_entry(table, i, "<unknown>");
This may have warranted a description in the commit message a la
Instead of setting unknown entries to "<unknown>" in the
interp_table, we teach interpolate() to replace entries with
NULL values by the empty string.
> diff --git a/log-tree.c b/log-tree.c
> index a642371..79502f4 100644
> --- a/log-tree.c
> +++ b/log-tree.c
> @@ -175,14 +175,15 @@ void show_log(struct rev_info *opt, const char *sep)
> * - The pretty-printed commit lacks a newline at the end
> * of the buffer, but we do want to make sure that we
> * have a newline there. If the separator isn't already
> - * a newline, add an extra one.
> + * a newline, add an extra one and do the same for the
> + * user format as well.
Here are still spaces instead of tabs.
These are only minor details; I don't know if Junio wants to fix them
himself.
Ciao,
Dscho
^ permalink raw reply
* Q: howto rebase
From: lode leroy @ 2007-09-25 14:46 UTC (permalink / raw)
To: git
I'm trying to understand how rebase works, but I need some help to get it.
Suppose I do the following workflow... (see below)
In "version B" I introduce the "fix c", but in "version D" I realize it
should have
been in some other place. (commit D moves the fix to its proper place).
A-B-C-D-E
Now I want to 'rewrite history'.
I would like to move commit D after B
A-B-D'-C'-E
and then fold the commits B and D' into a single commit.
A-B'-C'-E
I somehow managed to get this done using "rebase -i"
by exchanging the 2 appropriate lines, and then deleting the second one,
but I'd like to understand how to do this from the command line...
Could anyone enlighten me? I've read git-rebase(1) several times,
but don't seem to get it right...
cat > file <<EOF
a
b
d
e
g
h
EOF
git add file
git commit -m 'A' -a
cat > file <<EOF
a
b
d
e
g
c
h
EOF
git commit -m 'B' -a
cat > file <<EOF
a
b
d
e
f
g
c
h
EOF
git commit -m 'C' -a
cat > file <<EOF
a
b
c
d
e
f
g
h
EOF
git commit -m 'D' -a
cat > file <<EOF
a
b
c
d
e
f
g
h
i
EOF
git commit -m 'E' -a
_________________________________________________________________
A lot of passions? Collect all your personal info on one central location ,
for free! http://get.live.com/live/features
^ permalink raw reply
* [PATCH] Don't use "<unknown>" for unknown values of placeholders and suppress printing of empty user formats.
From: Michal Vitecek @ 2007-09-25 14:38 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Junio C Hamano
---
Sending the patch again in correct form (hopefully) as instructed by
Johannes Schindelin. Sorry for the hassle.
builtin-rev-list.c | 3 ++-
commit.c | 3 ---
interpolate.c | 6 +++++-
log-tree.c | 10 ++++++----
t/t6006-rev-list-format.sh | 8 --------
t/t7500-commit.sh | 4 ++--
6 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 3894633..0b74eb3 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -85,7 +85,8 @@ static void show_commit(struct commit *commit)
pretty_print_commit(revs.commit_format, commit, ~0,
&buf, &buflen,
revs.abbrev, NULL, NULL, revs.date_mode);
- printf("%s%c", buf, hdr_termination);
+ if (*buf)
+ printf("%s%c", buf, hdr_termination);
free(buf);
}
maybe_flush_or_die(stdout, "stdout");
diff --git a/commit.c b/commit.c
index 99f65ce..c9a1818 100644
--- a/commit.c
+++ b/commit.c
@@ -917,9 +917,6 @@ long format_commit_message(const struct commit *commit, const void *format,
}
if (msg[i])
table[IBODY].value = xstrdup(msg + i);
- for (i = 0; i < ARRAY_SIZE(table); i++)
- if (!table[i].value)
- interp_set_entry(table, i, "<unknown>");
do {
char *buf = *buf_p;
diff --git a/interpolate.c b/interpolate.c
index 0082677..2f727cd 100644
--- a/interpolate.c
+++ b/interpolate.c
@@ -76,8 +76,12 @@ unsigned long interpolate(char *result, unsigned long reslen,
/* Check for valid interpolation. */
if (i < ninterps) {
value = interps[i].value;
- valuelen = strlen(value);
+ if (!value) {
+ src += namelen;
+ continue;
+ }
+ valuelen = strlen(value);
if (newlen + valuelen + 1 < reslen) {
/* Substitute. */
strncpy(dest, value, valuelen);
diff --git a/log-tree.c b/log-tree.c
index a642371..79502f4 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -175,14 +175,15 @@ void show_log(struct rev_info *opt, const char *sep)
* - The pretty-printed commit lacks a newline at the end
* of the buffer, but we do want to make sure that we
* have a newline there. If the separator isn't already
- * a newline, add an extra one.
+ * a newline, add an extra one and do the same for the
+ * user format as well.
* - unlike other log messages, the one-line format does
* not have an empty line between entries.
*/
extra = "";
- if (*sep != '\n' && opt->commit_format == CMIT_FMT_ONELINE)
+ if (*sep != '\n' && (opt->commit_format == CMIT_FMT_ONELINE || opt->commit_format == CMIT_FMT_USERFORMAT))
extra = "\n";
- if (opt->shown_one && opt->commit_format != CMIT_FMT_ONELINE)
+ if (opt->shown_one && opt->commit_format != CMIT_FMT_ONELINE && opt->commit_format != CMIT_FMT_USERFORMAT)
putchar(opt->diffopt.line_termination);
opt->shown_one = 1;
@@ -298,7 +299,8 @@ void show_log(struct rev_info *opt, const char *sep)
if (opt->show_log_size)
printf("log size %i\n", len);
- printf("%s%s%s", msgbuf, extra, sep);
+ if (*msgbuf)
+ printf("%s%s%s", msgbuf, extra, sep);
free(msgbuf);
}
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index ad6d0b8..1e4541a 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -79,9 +79,7 @@ EOF
test_format encoding %e <<'EOF'
commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
EOF
test_format subject %s <<'EOF'
@@ -93,9 +91,7 @@ EOF
test_format body %b <<'EOF'
commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
EOF
test_format colors %Credfoo%Cgreenbar%Cbluebaz%Cresetxyzzy <<'EOF'
@@ -121,9 +117,7 @@ test_format complex-encoding %e <<'EOF'
commit f58db70b055c5718631e5c61528b28b12090cdea
iso8859-1
commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
EOF
test_format complex-subject %s <<'EOF'
@@ -142,9 +136,7 @@ and it will be encoded in iso8859-1. We should therefore
include an iso8859 character: ÂĄbueno!
commit 131a310eb913d107dd3c09a65d1651175898735d
-<unknown>
commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
-<unknown>
EOF
test_done
diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh
index f11ada8..abbf54b 100755
--- a/t/t7500-commit.sh
+++ b/t/t7500-commit.sh
@@ -81,7 +81,7 @@ test_expect_success 'explicit commit message should override template' '
git add foo &&
GIT_EDITOR=../t7500/add-content git commit --template "$TEMPLATE" \
-m "command line msg" &&
- commit_msg_is "command line msg<unknown>"
+ commit_msg_is "command line msg"
'
test_expect_success 'commit message from file should override template' '
@@ -90,7 +90,7 @@ test_expect_success 'commit message from file should override template' '
echo "standard input msg" |
GIT_EDITOR=../t7500/add-content git commit \
--template "$TEMPLATE" --file - &&
- commit_msg_is "standard input msg<unknown>"
+ commit_msg_is "standard input msg"
'
test_done
--
1.5.3.2
--
fuf (fuf@mageo.cz)
^ permalink raw reply related
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