* Re: [RFC] shallow clone
From: Johannes Schindelin @ 2006-01-30 12:13 UTC (permalink / raw)
To: Simon Richter; +Cc: Junio C Hamano, git
In-Reply-To: <43DDFF5C.30803@hogyros.de>
Hi,
On Mon, 30 Jan 2006, Simon Richter wrote:
> Johannes Schindelin wrote:
>
> > > . Set up `info/grafts` to lie to the local git that Linux kernel
> > > history began at v2.6.14 version.
>
> > Maybe also record this in .git/config, so that you can
>
> I like that "config" thing less and less every day. It appears to become a
> kind of registry, where having dedicated files for specific functionality
> would provide the robustness of tools not having to touch things they do not
> care about; but that's just personal opinion.
It is becoming sort of a registry: it contains metadata about the current
repository, easily available to scripts and programs.
I beg to differ on your personal opinion on the grounds that the
robustness comes from testing, not from diversity. I much prefer to have a
well tested config mechanism to having dozens of differently formatted
files with less-than-well tested parsers.
Thank you for the insights in your personal opinion anyway.
> > - disallow fetching from this repo, and
>
> Why? It's perfectly acceptable to pull from an incomplete repo, as long as you
> don't care about the old history.
Right. But should that be the default? I don't think so. Therefore:
disable it, and if the user is absolutely sure to do dumb things, she'll
have to enable it explicitely.
> > - easily extend the shallow copy to a larger shallow one, or a full one.
>
> Hrm, I think there should also be a way to shrink a repo and "forget" old
> history occasionally (obviously, use of that feature would be highly
> discouraged).
Yes. And you need information about how shallow it used to be. My
suggestion was to store that information at a place specific to that
repository (see above).
> > > . Run `git fetch git://.../linux-2.6 master`, with a local ref
> > > pointing at v2.6.14 commit, to pretend that we have everything
> > > up to v2.6.14 to `upload-pack` running on the other end.
>
> > How about refs/tags/start_shallow?
>
> No, as that would imply that cloning from such a repo is disallowed.
See above.
> IMO, it may be a lot more robust to just have a list of "cutoff" object ids in
> .git/shallow instead of messing with grafts here, as adding or removing a line
> from that file is an easier thing to do for porcelain (or by hand) than
> rewriting the grafts file. Whether that list would be inclusive or exclusive
> would need to be decided still.
The functionality of cutoff objects is included in grafts functionality,
so why should we spend time on reimplementing a subset of features?
IMHO, adding and removing lines from scripts is fragile.
I beg your pardon, you want to edit this information *by hand*? Wow.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC] shallow clone
From: Simon Richter @ 2006-01-30 11:58 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0601301220420.6424@wbgn013.biozentrum.uni-wuerzburg.de>
[-- Attachment #1: Type: text/plain, Size: 1523 bytes --]
Hi,
Johannes Schindelin wrote:
>>. Set up `info/grafts` to lie to the local git that Linux kernel
>> history began at v2.6.14 version.
> Maybe also record this in .git/config, so that you can
I like that "config" thing less and less every day. It appears to become
a kind of registry, where having dedicated files for specific
functionality would provide the robustness of tools not having to touch
things they do not care about; but that's just personal opinion.
> - disallow fetching from this repo, and
Why? It's perfectly acceptable to pull from an incomplete repo, as long
as you don't care about the old history.
> - easily extend the shallow copy to a larger shallow one, or a full one.
Hrm, I think there should also be a way to shrink a repo and "forget"
old history occasionally (obviously, use of that feature would be highly
discouraged).
>>. Run `git fetch git://.../linux-2.6 master`, with a local ref
>> pointing at v2.6.14 commit, to pretend that we have everything
>> up to v2.6.14 to `upload-pack` running on the other end.
> How about refs/tags/start_shallow?
No, as that would imply that cloning from such a repo is disallowed.
IMO, it may be a lot more robust to just have a list of "cutoff" object
ids in .git/shallow instead of messing with grafts here, as adding or
removing a line from that file is an easier thing to do for porcelain
(or by hand) than rewriting the grafts file. Whether that list would be
inclusive or exclusive would need to be decided still.
Simon
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 307 bytes --]
^ permalink raw reply
* Re: Two newbie question: "dead" branches and merging after cherry-pick.
From: Romano Giannetti @ 2006-01-30 11:44 UTC (permalink / raw)
To: git
First of all, 1000 thanks and please forgive me for the broken thread, I was
not subscribed to the list before so I did a copy-and-paste from the web
archive.
Junio C. Hamano wrote:
>
> You are done with what you did in the branch for now, but you
> have not merged the work to your day-to-day development "master"
> for some reason. In the meantime you would want to switch to
> other topic branches to work on other topics, and while working
> on them you do not want to "git branch" and "git show-branch" to
> show the topic you are done with but not merged yet. Later you
> would want to come back to it to do some interesting stuff with
> it (maybe finally merge into "master", or format-patch to send
> upstream). Is that what is happening here?
> If so, I would have chosen "postponed" not "dead" to describe
> the situation but you said "dead" and that is why I am wondering
> if I am getting you correctly.
Yes, you have understood perfectly. I called them "dead" because really I do
not think to come back to them ever, but I want to maintain that as "old
story", something of the style "that was an error, store it so that you will
never fall in it again".
>
> Yes. You have the tag under .git/refs which points at the tip
> of that postponed branch head, so the development trail will not
> be lost. When you are done with other topics and would want to
> come back to that topic again, you could do this:
>
> $ git tag hold/jc/gitlink jc/link ;# copy it to tags/
> $ git branch -D jc/link ;# delete it from heads/
>
> Now "git branch" would not show it, but "gitk --all" still would.
>
What I have done (and it seems to work perfectly) is
git checkout master
mkdir .git/refs/olds
mv .git/heads/test-bill-idea .git/olds
and it seems to work ok. Thanks!
> - Easier: suppose I cheery-picked "abababab" from branch "testing"
> to master branch. What will happen if later I decide to merge
> all "testing" to master branch? I will have a merge conflict (trying
> to apply two times the same fix) or not?
>
> This is easy to experiment so I'd suggest you to try it and tell
> us what you see, like this:
>
> $ git checkout -b test-merge-throwaway master
> $ git cherry-pick abababab
> $ ... play with it, maybe making a couple of commits
> $ git pull . testing
>
> I would not be surprised if this resolves cleanly. If abababab
> is the only thing that touches the set of paths it touches,
> other than what are in "testing" and what you did since
> "testing" forked from "master", it is likely that the merge
> would resolve cleanly.
>
> Otherwise you would likely to see conflicts --- in which case
> you may want to suggest if/how we can reduce it. "cherry-pick"
> without -r drops a hint of which commit was picked in the commit
> log so it _might_ be a good idea to teach git to optionally take
> that information into account while doing the merge. I dunno.
>
> Once you are done experimenting, you can come back to master and
> delete the test-merge-throwaway branch:
>
> $ git checkout master
> $ git branch -D test-merge-throwaway
>
Thanks. I will play a bit with it. I sometime have a bit of fear to not
being able to come back to a good state. I will do my homework and study a
bit more git checkout, branch and reset (this latter gives me a bit of
headheache last time... ;-) ).
Thanks a lot.
--
Romano Giannetti - Univ. Pontificia Comillas (Madrid, Spain)
Electronic Engineer - phone +34 915 422 800 ext 2416 fax +34 915 596 569
http://www.dea.icai.upcomillas.es/romano/
^ permalink raw reply
* Re: [RFC] shallow clone
From: Johannes Schindelin @ 2006-01-30 11:39 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7voe1uchet.fsf@assigned-by-dhcp.cox.net>
Hi,
On Sun, 29 Jan 2006, Junio C Hamano wrote:
> Strategy
> --------
>
> We have `info/grafts` mechanism to fake parent information for
> commit objects. Using this facility, we could roughly do:
>
> . Download the full tree for v2.6.14 commit and store its
> objects locally.
On first read, I mistook "tree" for "commit"...
> . Set up `info/grafts` to lie to the local git that Linux kernel
> history began at v2.6.14 version.
Maybe also record this in .git/config, so that you can
- disallow fetching from this repo, and
- easily extend the shallow copy to a larger shallow one, or a full one.
> . Run `git fetch git://.../linux-2.6 master`, with a local ref
> pointing at v2.6.14 commit, to pretend that we have everything
> up to v2.6.14 to `upload-pack` running on the other end.
How about refs/tags/start_shallow?
> . Update the `origin` branch with the master commit object name
> we just fetched from Linus.
>
> Design
> ------
>
> [...]
>
> Another functionality we would need is to tell `upload-pack` to
> use `info/grafts` of downloader's choice. With this, after
> fetching the objects for v2.6.14 commit, the downloader can set
> up its own grafts file to cauterize the development history at
> v2.6.14, and tell the `upload-pack` to pretend the kernel
> history starts at that commit, while sending the tip of Linus'
> development track to us.
Why not just start another fetch? Then, "have <refs/tags/start_shallow>"
would be sent, and upload-pack does the right thing?
If you absolutely want to get only one pack, which then is stored as-is,
upload-pack could start two rev-list processes: one for the tree and one
for all the rest.
> [...]
>
> [NOTE]
> Most likely this is not directly run by the user but is run as
> the first command invoked by the shallow clone script.
Better make it an option to git-clone
> 4. `upload-pack` notices this is a single commit request, and
> sends an ACK if it can satisfy the request (or a NAK if it
> can't, e.g. it does not have the asked commit). Instead of
> doing the usual `get_common_commits` followed by
> `create_pack_file`, it does:
>
> $ git rev-list -n1 --objects $commit | git pack-object
Here it could say
(git rev-list -n1 --objects $commit_since; git rev-list --objects
^$commit_since $commit) | git pack-object
If the former is still needed (e.g. for git-tar-remote-tree), we could
distinguish "single <ref>" and "shallow <ref>" commands.
> [...]
>
> The second phase of the shallow clone is to fetch the history
> since v2.6.14 to the tip.
As I outlined above, I don't see the need for this.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] cvsexportcommit: add some examples to the documentation
From: Junio C Hamano @ 2006-01-30 7:36 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git, Randal L. Schwartz
In-Reply-To: <11386028552572-git-send-email-martin@catalyst.net.nz>
Thanks both.
^ permalink raw reply
* [RFC] shallow clone
From: Junio C Hamano @ 2006-01-30 7:18 UTC (permalink / raw)
To: git
Shallow History Cloning
=======================
One good thing about git repository is that each clone is a
freestanding and complete entity, and you can keep developing in
it offline, without talking to the outside world, knowing that
you can sync with them later when online.
It is also a bad thing. It gives people working on projects
with long development history stored in CVS a heart attack when
we tell them that their clones need to store the whole history.
There was a suggestion by Linus to allow a partial clone using a
syntax like this:
$ git clone --since=v2.6.14 git://.../linux-2.6/ master
Here is an outline of what changes are needed to the current
core to do this.
Strategy
--------
We have `info/grafts` mechanism to fake parent information for
commit objects. Using this facility, we could roughly do:
. Download the full tree for v2.6.14 commit and store its
objects locally.
. Set up `info/grafts` to lie to the local git that Linux kernel
history began at v2.6.14 version.
. Run `git fetch git://.../linux-2.6 master`, with a local ref
pointing at v2.6.14 commit, to pretend that we have everything
up to v2.6.14 to `upload-pack` running on the other end.
. Update the `origin` branch with the master commit object name
we just fetched from Linus.
There are some issues.
. In the fetch above to obtain everything after v2.6.14, and
future runs of `git fetch origin`, if a blob that is in the
commit being fetched happens to match what used to be in a
commit that is older than v2.6.14 (e.g. a patch was reverted),
`upload-pack` running on the other end is free to omit sending
it, because we are telling it that we are up to date with
respect to v2.6.14. Although I think the current `rev-list
--objects` implementation does not always do such a revert
optimization if the revert is to a blob in a revision that is
sufficiently old, it is free to optimize more aggressively in
the future.
. Later when the user decides to fetch older history, the
operation can become a bit cumbersome.
I think the latter one is cumbersome but is doable -- we could
do the equivalent of:
$ git clone --since=v2.6.13 origin v2.6.14
place all the objects obtained by such a clone/fetch operation
and remember that now we have history beginning at v2.6.13. So
let's worry about that later.
For the first issue, we need to have the other end cooperate
while fetching from it. If the other end also thinks the
development started at v2.6.14, even if we tell that we have the
history up to v2.6.14 (or a commit we obtained since then),
there is no way for `upload-pack` running there to optimize too
agressively and assume we have a blob that appeared in v2.6.13.
More simply, we do not have to tell them we have anything -- if
the other end thinks the epoch is at v2.6.14, only commits that
comes later will be sent to us.
Design
------
First, to bootstrap the process, we would need to add a way to
obtain all objects associated with a commit. We could do a new
program, or we could implement this as a protocol extension to
`upload-pack`. My current inclination is the latter.
When talking with `upload-pack` that supports this extension,
the downloader can give one commit object name and get a pack
that contains all the objects in the tree associated with that
commit, plus the commit object itself. This is a rough
equivalent of running the commit walker with the `-t` flag.
Another functionality we would need is to tell `upload-pack` to
use `info/grafts` of downloader's choice. With this, after
fetching the objects for v2.6.14 commit, the downloader can set
up its own grafts file to cauterize the development history at
v2.6.14, and tell the `upload-pack` to pretend the kernel
history starts at that commit, while sending the tip of Linus'
development track to us.
Using the extended protocol (let's call it 'shallow' extension),
a clone to create a repository that has only recent kernel
history since v2.6.14 goes like this:
The first client is to fetch the v2.6.14 itself.
[NOTE]
Most likely this is not directly run by the user but is run as
the first command invoked by the shallow clone script.
1. The `fetch-pack` command acquires a new option, `--single`:
$ git-fetch-pack --single git://.../linux-2.6/ v2.6.14
This talks with `upload-pack` on the kernel.org server via
`git-daemon`.
2. `upload-pack` tells the fetcher what commits it has,
what their refs are, and what protocol extensions it
supports, as usual.
3. If it does not see `shallow` extension supported, there is no
way to get a single tree, so things fail here. Otherwise, it
sends `single X{40}\0` request, instead of the usual `want`
line. The object name sent here is the desired commit.
4. `upload-pack` notices this is a single commit request, and
sends an ACK if it can satisfy the request (or a NAK if it
can't, e.g. it does not have the asked commit). Instead of
doing the usual `get_common_commits` followed by
`create_pack_file`, it does:
$ git rev-list -n1 --objects $commit | git pack-object
and sends the result out.
5. The fetcher checks the ACK and receives the objects.
After the above exchange, we have downloaded v2.6.14 commit and
its objects but not its history. `git-fetch-pack` would output
the tag object name for `v2.6.14` and we would stash it away in
`$GIT_DIR/FETCH_HEAD` as usual. Then we set up `info/grafts`
with this:
$ git rev-parse FETCH_HEAD^{commit} >"$GIT_DIR/info/grafts"
This cauterizes the history on our end.
The second phase of the shallow clone is to fetch the history
since v2.6.14 to the tip.
1. The `fetch-pack` command is run as usual. Most likely the
command line run by the shallow clone script would be:
$ git fetch-pack git://.../linux-2.6/ master
Notice there is nothing magical about it. It is just the
business as usual.
2. `upload-pack` does its usual greeting to the downloader.
3. We notice `shallow` extension again, and first send out
`graft X{40}\0` request. The syntax of graft request would
be `graft ` followed by one or more commit object names on a
line separated with SP. After sending out all the needed
graft requests (in this example there is only one, to
cauterize the history at v2.6.14), it does the usual `want
X{40}\0multi_ack` and a flush.
4. `upload-pack` notices graft requests, reinitializes its graft
information with what it receives from the other end, and
then records `want`.
5. After the above steps, the usual `upload-pack` vs
`fetch-pack` exchange continues and objects needed to
complete the Linus' tip of development trail for somebody who
has v2.6.14 are sent in a pack. The difference from the
usual operation is that `upload-pack` during this run thinks
v2.6.14 commit does not have any parent.
The exact sequence from the second part of the initial "shallow
clone" can be used for further updates.
There is a small issue about the actual implementation. In the
above description I pretended that `upload-pack` can be told to
use phony grafts information, but in the current implementation
the program that needs to use phony grafts information is
`rev-list` spawned from it. We _could_ point GIT_GRAFT_FILE
environment variable point at a temporary file while we do so,
but I'd like to avoid using a temporary file if possible, given
that `upload-pack` is run from `git-daemon`. Maybe we could
give --read-graft-from-stdin flag to `rev-list` for this
purpose.
Anybody want to try?
^ permalink raw reply
* [PATCH] cvsexportcommit: add some examples to the documentation
From: Martin Langhoff @ 2006-01-30 6:34 UTC (permalink / raw)
To: git; +Cc: Martin Langhoff
Updated with Randall Schwartz's suggestion.
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
Apologies! One of these days I'll get it right on the first try ;-)
Documentation/git-cvsexportcommit.txt | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
69c980351a6d74d033a8d70fb37970c71ff8e855
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 13cbf3b..e2540fb 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -17,6 +17,7 @@ Exports a commit from GIT to a CVS check
to merge patches from a git repository into a CVS repository.
Execute it from the root of the CVS working copy. GIT_DIR must be defined.
+See examples below.
It does its best to do the safe thing, it will check that the files are
unchanged and up to date in the CVS checkout, and it will not autocommit
@@ -41,6 +42,26 @@ OPTIONS
-v::
Verbose.
+EXAMPLES
+--------
+
+Merge one patch into CVS::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cvsexportcommit -v <commit-sha1>
+$ cvs commit -F .mgs <files>
+------------
+
+Merge pending patches into CVS automatically -- only if you really know what you are doing ::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cherry cvshead myhead | sed -n 's/^+ //p' | xargs -l1 git-cvsexportcommit -c -p -v
+------------
+
Author
------
Written by Martin Langhoff <martin@catalyst.net.nz>
--
1.1.6.g170f-dirty
^ permalink raw reply related
* Re: [PATCH] cvsexportcommit: add some examples to the documentation
From: Randal L. Schwartz @ 2006-01-30 6:30 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
In-Reply-To: <1138602541556-git-send-email-martin@catalyst.net.nz>
>>>>> "Martin" == Martin Langhoff <martin@catalyst.net.nz> writes:
Martin> +$ git-cherry cvshead myhead | sed 's/^+ //p' | xargs -l1 git-cvsexportcommit -c -p -v
But you forgot the -n. :)
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* [PATCH] cvsexportcommit: add some examples to the documentation
From: Martin Langhoff @ 2006-01-30 6:29 UTC (permalink / raw)
To: git; +Cc: Martin Langhoff
Updated with Randall Schwartz's suggestion
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
Documentation/git-cvsexportcommit.txt | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
69c980351a6d74d033a8d70fb37970c71ff8e855
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 13cbf3b..e2540fb 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -17,6 +17,7 @@ Exports a commit from GIT to a CVS check
to merge patches from a git repository into a CVS repository.
Execute it from the root of the CVS working copy. GIT_DIR must be defined.
+See examples below.
It does its best to do the safe thing, it will check that the files are
unchanged and up to date in the CVS checkout, and it will not autocommit
@@ -41,6 +42,26 @@ OPTIONS
-v::
Verbose.
+EXAMPLES
+--------
+
+Merge one patch into CVS::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cvsexportcommit -v <commit-sha1>
+$ cvs commit -F .mgs <files>
+------------
+
+Merge pending patches into CVS automatically -- only if you really know what you are doing ::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cherry cvshead myhead | sed 's/^+ //p' | xargs -l1 git-cvsexportcommit -c -p -v
+------------
+
Author
------
Written by Martin Langhoff <martin@catalyst.net.nz>
--
1.1.6.g170f-dirty
^ permalink raw reply related
* Re: [PATCH] cvsexportcommit: add some examples to the documentation
From: Randal L. Schwartz @ 2006-01-30 6:25 UTC (permalink / raw)
To: Martin Langhoff; +Cc: git
In-Reply-To: <11386015522537-git-send-email-martin@catalyst.net.nz>
>>>>> "Martin" == Martin Langhoff <martin@catalyst.net.nz> writes:
Martin> +$ git-cherry cvshead myhead | grep '^+' | sed 's/^+ //' | xargs -l1 git-cvsexportcommit -c -p -v
My idiom for that grep/sed would be:
... | sed -n 's/^+ //p' | ...
Then the grep is not needed, because you're printing only the ones
that you've also modified in a useful way.
Yes, I did a heckuva lot more shell programming long before Perl existed. :)
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* [PATCH] cvsexportcommit: add some examples to the documentation
From: Martin Langhoff @ 2006-01-30 6:12 UTC (permalink / raw)
To: git; +Cc: Martin Langhoff
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
Documentation/git-cvsexportcommit.txt | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
69c980351a6d74d033a8d70fb37970c71ff8e855
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index 13cbf3b..e2540fb 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -17,6 +17,7 @@ Exports a commit from GIT to a CVS check
to merge patches from a git repository into a CVS repository.
Execute it from the root of the CVS working copy. GIT_DIR must be defined.
+See examples below.
It does its best to do the safe thing, it will check that the files are
unchanged and up to date in the CVS checkout, and it will not autocommit
@@ -41,6 +42,26 @@ OPTIONS
-v::
Verbose.
+EXAMPLES
+--------
+
+Merge one patch into CVS::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cvsexportcommit -v <commit-sha1>
+$ cvs commit -F .mgs <files>
+------------
+
+Merge pending patches into CVS automatically -- only if you really know what you are doing ::
++
+------------
+$ export GIT_DIR=~/project/.git
+$ cd ~/project_cvs_checkout
+$ git-cherry cvshead myhead | grep '^+' | sed 's/^+ //' | xargs -l1 git-cvsexportcommit -c -p -v
+------------
+
Author
------
Written by Martin Langhoff <martin@catalyst.net.nz>
--
1.1.6.g170f-dirty
^ permalink raw reply related
* [PATCH] exportcommit: replace backticks with safe_pipe_capture() or system() - initial pass
From: Martin Langhoff @ 2006-01-30 6:12 UTC (permalink / raw)
To: git; +Cc: Martin Langhoff
Replaced backticks with potentially troublesome unescaped input with
safe_pipe_capture().
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
NOTE: this has only seen some limited testing. Needs review.
---
git-cvsexportcommit.perl | 53 +++++++++++++++++++++++++++++-----------------
1 files changed, 33 insertions(+), 20 deletions(-)
dcd2656443a39d64cc899fe1709a6bb35e89561d
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index d5fbee7..7b3a3d3 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -27,7 +27,7 @@ print Dumper(@ARGV);
# resolve target commit
my $commit;
$commit = pop @ARGV;
-$commit = `git-rev-parse --verify "$commit"^0`;
+$commit = safe_pipe_capture('git-rev-parse', '--verify', "$commit^0");
chomp $commit;
if ($?) {
die "The commit reference $commit did not resolve!";
@@ -37,7 +37,7 @@ if ($?) {
my $parent;
if (@ARGV) {
$parent = pop @ARGV;
- $parent = `git-rev-parse --verify "$parent"^0"`;
+ $parent = safe_pipe_capture('git-rev-parse', '--verify', "$parent^0");
chomp $parent;
if ($?) {
die "The parent reference did not resolve!";
@@ -45,7 +45,7 @@ if (@ARGV) {
}
# find parents from the commit itself
-my @commit = `git-cat-file commit $commit`;
+my @commit = safe_pipe_capture('git-cat-file', 'commit', $commit);
my @parents;
foreach my $p (@commit) {
if ($p =~ m/^$/) { # end of commit headers, we're done
@@ -81,12 +81,12 @@ $opt_v && print "Applying to CVS commit
$? && die "Error extracting the commit message";
my (@afiles, @dfiles, @mfiles);
-my @files = `git-diff-tree -r $parent $commit`;
+my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
print @files;
$? && die "Error in git-diff-tree";
foreach my $f (@files) {
chomp $f;
- my @fields = split(m/\s+/, $f);
+ my @fields = split(m!\s+!, $f);
if ($fields[4] eq 'A') {
push @afiles, $fields[5];
}
@@ -104,18 +104,19 @@ undef @files; # don't need it anymore
# check that the files are clean and up to date according to cvs
my $dirty;
foreach my $f (@afiles) {
- my $status = `cvs -q status "$f" | grep '^File: '`;
-
- unless ($status =~ m/Status: Unknown$/) {
- $dirty = 1;
+ # This should return only one value
+ my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
+ if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
+ unless ($status[0] =~ m/Status: Unknown$/) {
+ $dirty = 1;
warn "File $f is already known in your CVS checkout!\n";
}
}
foreach my $f (@mfiles, @dfiles) {
# TODO:we need to handle removed in cvs
- my $status = `cvs -q status "$f" | grep '^File: '`;
-
- unless ($status =~ m/Status: Up-to-date$/) {
+ my @status = grep(m/^File/, safe_pipe_capture('cvs', '-q', 'status' ,$f));
+ if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
+ unless ($status[0] =~ m/Status: Up-to-date$/) {
$dirty = 1;
warn "File $f not up to date in your CVS checkout!\n";
}
@@ -132,18 +133,17 @@ if ($dirty) {
print "'Patching' binary files\n";
-my @bfiles = `git-diff-tree -p $parent $commit | grep '^Binary'`;
+my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit));
@bfiles = map { chomp } @bfiles;
foreach my $f (@bfiles) {
# check that the file in cvs matches the "old" file
# extract the file to $tmpdir and comparre with cmp
- my $tree = `git-rev-parse $parent^{tree} `;
+ my $tree = safe_pipe_capture('git-rev-parse', "$parent^{tree}");
chomp $tree;
my $blob = `git-ls-tree $tree "$f" | cut -f 1 | cut -d ' ' -f 3`;
chomp $blob;
`git-cat-file blob $blob > $tmpdir/blob`;
- `cmp -q $f $tmpdir/blob`;
- if ($?) {
+ if (system('cmp', '-q', $f, "$tmpdir/blob")) {
warn "Binary file $f in CVS does not match parent.\n";
$dirty = 1;
next;
@@ -175,7 +175,7 @@ if (($? >> 8) == 2) {
}
foreach my $f (@afiles) {
- `cvs add $f`;
+ system('cvs', 'add', $f);
if ($?) {
$dirty = 1;
warn "Failed to cvs add $f -- you may need to do it manually";
@@ -183,7 +183,7 @@ foreach my $f (@afiles) {
}
foreach my $f (@dfiles) {
- `cvs rm -f $f`;
+ system('cvs', 'rm', '-f', $f);
if ($?) {
$dirty = 1;
warn "Failed to cvs rm -f $f -- you may need to do it manually";
@@ -204,7 +204,7 @@ if ($dirtypatch) {
if ($opt_c) {
print "Autocommit\n $cmd\n";
- print `cvs commit -F .msg $commitfiles 2>&1`;
+ print safe_pipe_capture('cvs', 'commit', '-F', '.msg', @afiles, @mfiles, @dfiles);
if ($?) {
cleanupcvs(@files);
die "Exiting: The commit did not succeed";
@@ -224,10 +224,23 @@ END
sub cleanupcvs {
my @files = @_;
foreach my $f (@files) {
- `cvs -q update -C "$f"`;
+ system('cvs', '-q', 'update', '-C', $f);
if ($?) {
warn "Warning! Failed to cleanup state of $f\n";
}
}
}
+# An alterative to `command` that allows input to be passed as an array
+# to work around shell problems with weird characters in arguments
+# if the exec returns non-zero we die
+sub safe_pipe_capture {
+ my @output;
+ if (my $pid = open my $child, '-|') {
+ @output = (<$child>);
+ close $child or die join(' ',@_).": $! $?";
+ } else {
+ exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
+ }
+ return wantarray ? @output : join('',@output);
+}
--
1.1.6.g170f-dirty
^ permalink raw reply related
* [PATCH] cvsimport: Add -S <skipfileregex> support and -v announces files retrieved
From: Martin Langhoff @ 2006-01-30 6:12 UTC (permalink / raw)
To: git; +Cc: Martin Langhoff
A couple of things that seem to help importing broken CVS repos...
-S '<slash-delimited-regex>' skips files with a matching path
-v prints file name and version before fetching from cvs
Signed-off-by: Martin Langhoff <martin@catalyst.net.nz>
---
You can now see what file fetch is breaking the import and
you can then tell cvsimport to skip it.
git-cvsimport.perl | 19 +++++++++++++++----
1 files changed, 15 insertions(+), 4 deletions(-)
d42ad86243882f6937b7af8b1ae10c0ec899a8a3
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index fc207fc..00fc3ba 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -29,7 +29,7 @@ use IPC::Open2;
$SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
-our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A);
+our($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S);
my (%conv_author_name, %conv_author_email);
sub usage() {
@@ -37,7 +37,7 @@ sub usage() {
Usage: ${\basename $0} # fetch/update GIT from CVS
[-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
[-p opts-for-cvsps] [-C GIT_repository] [-z fuzz] [-i] [-k] [-u]
- [-s subst] [-m] [-M regex] [CVS_module]
+ [-s subst] [-m] [-M regex] [-S regex] [CVS_module]
END
exit(1);
}
@@ -85,7 +85,7 @@ sub write_author_info($) {
close ($f);
}
-getopts("hivmkuo:d:p:C:z:s:M:P:A:") or usage();
+getopts("hivmkuo:d:p:C:z:s:M:P:A:S:") or usage();
usage if $opt_h;
@ARGV <= 1 or usage();
@@ -579,7 +579,7 @@ unless($pid) {
my $state = 0;
my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
-my(@old,@new);
+my(@old,@new,@skipped);
my $commit = sub {
my $pid;
while(@old) {
@@ -675,6 +675,11 @@ my $commit = sub {
substr($logmsg,32767) = "" if length($logmsg) > 32767;
$logmsg =~ s/[\s\n]+\z//;
+ if (@skipped) {
+ $logmsg .= "\n\n\nSKIPPED:\n\t";
+ $logmsg .= join("\n\t", @skipped) . "\n";
+ }
+
print $pw "$logmsg\n"
or die "Error writing to git-commit-tree: $!\n";
$pw->close();
@@ -832,6 +837,12 @@ while(<CVS>) {
my $fn = $1;
my $rev = $3;
$fn =~ s#^/+##;
+ if ($opt_S && $fn =~ m/$opt_S/) {
+ print "SKIPPING $fn v $rev\n";
+ push(@skipped, $fn);
+ next;
+ }
+ print "Fetching $fn v $rev\n" if $opt_v;
my ($tmpname, $size) = $cvs->file($fn,$rev);
if($size == -1) {
push(@old,$fn);
--
1.1.6.g170f-dirty
^ permalink raw reply related
* Re: git push -f documentation
From: Junio C Hamano @ 2006-01-30 1:53 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: git
In-Reply-To: <20060130014050.GA18945@fieldses.org>
"J. Bruce Fields" <bfields@fieldses.org> writes:
> Surely the documentation here is exactly backwards? Or am I
> missing something?--b.
Thanks.
^ permalink raw reply
* git push -f documentation
From: J. Bruce Fields @ 2006-01-30 1:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Surely the documentation here is exactly backwards? Or am I
missing something?--b.
---
Documentation/git-push.txt | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
1391326bf55bc9a9deb52a872671f29c70c0a4de
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 365cfd4..a0ef61d 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -35,10 +35,10 @@ include::pull-fetch-param.txt[]
line.
-f, \--force::
- Usually, the command refuses to update a local ref that is
- not an ancestor of the remote ref used to overwrite it.
- This flag disables the check. What this means is that the
- local repository can lose commits; use it with care.
+ Usually, the command refuses to update a remote ref that is
+ not a descendent of the local ref used to overwrite it.
+ This flag disables the check. This can cause the
+ remote repository to lose commits; use it with care.
Author
--
0.99.8b.g3480-dirty
^ permalink raw reply related
* Re: [PATCH] diff: add --no-diff-deleted to make -p more pleasant
From: Eric Wong @ 2006-01-30 0:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy80ykd3j.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > This is a feature I've stol^Wborrowed from svn that I find very
> > useful since I usually don't care to see what I've deleted.
>
> There is a thing called --diff-filter, and
>
> git diff -p --no-diff-deleted
>
> is equivalent to
>
> git diff -p --diff-filter=AM
Cool, didn't notice this feature before. Thanks.
> when you are not using rename/copy detection (and a byte
> shorter). Or maybe improve its syntax to also take:
>
> --diff-filter=-D
>
> That is, a minus followed by list of undesired change class
> letters.
Hmm.. maybe another day. AM is good enough for now.
--
Eric Wong
^ permalink raw reply
* [PATCH] rev-{list,parse}: allow -<n> as shorthand for --max-count=<n>
From: Eric Wong @ 2006-01-30 0:28 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git list
In-Reply-To: <7v64o2kcym.fsf@assigned-by-dhcp.cox.net>
This will be enabled unless POSIXLY_CORRECT or POSIX_ME_HARDER is set
in the environment.
Some versions of head(1) and tail(1) allow their line limits to be
parsed this way. I find --max-count to be a commonly used option,
and also similar in spirit to head/tail, so I decided to make life
easier on my worn out (and lazy :) fingers with this patch.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
git-compat-util.h | 8 ++++++++
rev-list.c | 5 +++++
rev-parse.c | 4 ++++
3 files changed, 17 insertions(+), 0 deletions(-)
7a8d6dda7dacadc90377fc56d28d5d03493199c4
diff --git a/git-compat-util.h b/git-compat-util.h
index f982b8e..b2512ba 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -154,4 +154,12 @@ static inline int sane_case(int x, int h
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
+
+static inline int posixly_correct(void)
+{
+ if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
+ return 1;
+ return 0;
+}
+
#endif
diff --git a/rev-list.c b/rev-list.c
index 4565755..f29d32a 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -749,6 +749,11 @@ int main(int argc, const char **argv)
struct commit *commit;
unsigned char sha1[20];
+ /* accept, -<digit>, like some versions of head/tail */
+ if (!posixly_correct() && (*arg == '-') && isdigit(arg[1])) {
+ max_count = atoi(arg + 1);
+ continue;
+ }
if (!strcmp(arg, "-n")) {
if (++i >= argc)
die("-n requires an argument");
diff --git a/rev-parse.c b/rev-parse.c
index 3c99a79..2966a33 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -53,6 +53,10 @@ static int is_rev_argument(const char *a
};
const char **p = rev_args;
+ /* accept, -<digit>, like some versions of head/tail */
+ if (!posixly_correct() && (*arg == '-') && isdigit(arg[1]))
+ return 1;
+
for (;;) {
const char *str = *p++;
int len;
--
1.1.5.ga7f5-dirty
^ permalink raw reply related
* [PATCH] rev-{list,parse}: allow -n<n> as shorthand for --max-count=<n>
From: Eric Wong @ 2006-01-30 0:26 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git list
In-Reply-To: <20060130002501.GB15482@Muzzle>
Both -n<n> and -n <n> are supported. POSIX versions of head(1) and
tail(1) allow their line limits to be parsed this way. I find
--max-count to be a commonly used option, and also similar in spirit to
head/tail, so I decided to make life easier on my worn out (and lazy :)
fingers with this patch.
Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
rev-list.c | 10 ++++++++++
rev-parse.c | 15 +++++++++++++++
2 files changed, 25 insertions(+), 0 deletions(-)
a7f5327966f8ccdf887f3c63db3147135ff20983
diff --git a/rev-list.c b/rev-list.c
index 0b142c1..4565755 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -749,6 +749,16 @@ int main(int argc, const char **argv)
struct commit *commit;
unsigned char sha1[20];
+ if (!strcmp(arg, "-n")) {
+ if (++i >= argc)
+ die("-n requires an argument");
+ max_count = atoi(argv[i]);
+ continue;
+ }
+ if (!strncmp(arg,"-n",2)) {
+ max_count = atoi(arg + 2);
+ continue;
+ }
if (!strncmp(arg, "--max-count=", 12)) {
max_count = atoi(arg + 12);
continue;
diff --git a/rev-parse.c b/rev-parse.c
index d2f0864..3c99a79 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -165,6 +165,21 @@ int main(int argc, char **argv)
show_file(arg);
continue;
}
+ if (!strcmp(arg,"-n")) {
+ if (++i >= argc)
+ die("-n requires an argument");
+ if ((filter & DO_FLAGS) && (filter & DO_REVS)) {
+ show(arg);
+ show(argv[i]);
+ }
+ continue;
+ }
+ if (!strncmp(arg,"-n",2)) {
+ if ((filter & DO_FLAGS) && (filter & DO_REVS))
+ show(arg);
+ continue;
+ }
+
if (*arg == '-') {
if (!strcmp(arg, "--")) {
as_is = 1;
--
1.1.5.ga7f5-dirty
^ permalink raw reply related
* Re: [PATCH] rev-{list,parse}: allow -n<n> as shorthand for --max-count=<n>
From: Eric Wong @ 2006-01-30 0:25 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git list
In-Reply-To: <7vbqxukcyo.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
> Eric Wong <normalperson@yhbt.net> writes:
>
> > Both -n<n> and -n <n> are supported. POSIX versions of head(1) and
> > tail(1) allow their line limits to be parsed this way. I find
> > --max-count to be a commonly used option, and also similar in spirit to
> > head/tail, so I decided to make life easier on my worn out (and lazy :)
> > fingers with this patch.
>
> I agree with this in principle.
>
> > diff --git a/rev-parse.c b/rev-parse.c
> > index 7abad35..3790463 100644
> > --- a/rev-parse.c
> > +++ b/rev-parse.c
> > @@ -21,6 +21,7 @@ static char *def = NULL;
> > static int show_type = NORMAL;
> > static int symbolic = 0;
> > static int output_sq = 0;
> > +static int next_arg_is_rev = 0;
>
> Do you need this here, or can it be made auto in main()?
Oops, I had changes in is_rev_argument() that I eventually
moved entirely to main(). Cleaned up patch on the way.
--
Eric Wong
^ permalink raw reply
* Re: No merge strategy handled the merge (git version 1.1.GIT)
From: Junio C Hamano @ 2006-01-29 23:50 UTC (permalink / raw)
To: Roberto Nibali; +Cc: git
In-Reply-To: <43DD52ED.7090503@drugphish.ch>
Roberto Nibali <ratz@drugphish.ch> writes:
> ... "not reading code before commenting" omitted ...
> On top of that "-D" did/does
> not seem to be documented...
Well, initially, not documenting it was done somewhat
deliberately, because -D is an operation that would lose
information. Running the command with -d option would reveal
its existence after telling the user why we do not let it be
deleted by default.
^ permalink raw reply
* Re: No merge strategy handled the merge (git version 1.1.GIT)
From: Roberto Nibali @ 2006-01-29 23:42 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: git
In-Reply-To: <20060129120344.GB4815@c165.ib.student.liu.se>
>> raise ProgramError(progStr, e.strerror)
>> ProgramError: merge -L HEAD/net/ipv4/ipvs/ip_vs_ctl.c -L
>> orig/net/ipv4/ipvs/ip_vs_ctl.c -L
>> 3ee68c4af3fd7228c1be63254b9f884614f9ebb2/net/ipv4/ipvs/ip_vs_ctl.c
>> .merge_file_uofMwv .merge_file_hcesLs .merge_file_TwtEqw: No such file
>> or directory
>> No merge strategy handled the merge.
>>
>
> The problem is that merge(1), which is used for file-level merges,
> couldn't be found. Is it installed on your system? If you use Linux,
> it is usually found in the "rcs" package in your favorite
> distribution.
That's it, I've installed it now.
> This have came up a couple of times now, we should probably make this
> error message a bit less cryptic. I will send a patch in a separate
> mail.
Thanks.
> If your repository is in the state that the failed git-pull left it
> in, then the following actions should merge your changes with Linus'
> tree.
>
> 1. Install merge(1)
> 2. Run 'git reset --hard' (NOTE: Be careful with this command. It will
> revert any uncommitted changes you may have in your working directory!)
> 3. Run 'git pull'
This worked. And as you've mentioned, I lost the uncommitted changes.
>> Oh, btw, how is git branch -D supposed to work? Isn't there some code
>> missing?
>
> Could you be a bit more specific? Do you mean that there is code
> missing in git-branch.sh? What happens when you run 'git branch -D
> <some branch>'? It seems to work fine here.
Well, I was trying to understand git a bit better, so I started reading
the source code and just found that -D wasn't documented on my system,
even after a
git clone rsync://git.kernel.org/pub/scm/git/git.git/ GIT_HEAD
I'm talking about following excerpt which I've looked at for 2 minutes:
#!/bin/sh
USAGE='[-d <branch>] | [[-f] <branch> [start-point]]'
LONG_USAGE='If no arguments, show available branches and mark current
branch with a star.
If one argument, create a new branch <branchname> based off of current HEAD.
If two arguments, create a new branch <branchname> based off of
<start-point>.'
SUBDIRECTORY_OK='Yes'
. git-sh-setup
headref=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
delete_branch () {
option="$1"
shift
for branch_name
do
case ",$headref," in
",$branch_name,")
die "Cannot delete the branch you are on." ;;
,,)
die "What branch are you on anyway?" ;;
esac
branch=$(cat "$GIT_DIR/refs/heads/$branch_name") &&
branch=$(git-rev-parse --verify "$branch^0") ||
die "Seriously, what branch are you talking about?"
case "$option" in
-D)
;;
[...]
This is slightly confusing, since I didn't see the shift after
delete_branch so it looked like a noop. On top of that "-D" did/does not
seem to be documented. Skimming over your patch you've sent later to
this list, it appears you've fixed the documentation.
Best regards,
Roberto Nibali, ratz
--
echo
'[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq' | dc
^ permalink raw reply
* Re: [PATCH] merge-recursive: Improve the error message printed when merge(1) isn't found.
From: Roberto Nibali @ 2006-01-29 23:42 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: git, junkio
In-Reply-To: <20060129121608.GC4815@c165.ib.student.liu.se>
> - [out, code] = runProgram(['merge',
> - '-L', branch1Name + '/' + aPath,
> - '-L', 'orig/' + oPath,
> - '-L', branch2Name + '/' + bPath,
> - src1, orig, src2], returnCode=True)
> + try:
> + [out, code] = runProgram(['merge',
> + '-L', branch1Name + '/' + aPath,
> + '-L', 'orig/' + oPath,
> + '-L', branch2Name + '/' + bPath,
> + src1, orig, src2], returnCode=True)
> + except ProgramError, e:
> + print >>sys.stderr, e
> + die("Failed to execute 'merge'. merge(1) is used as the "
> + "file-level merge tool. Is 'merge' in your path?")
This has my vote as well.
Thanks for your support,
Roberto Nibali, ratz
--
echo
'[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq' | dc
^ permalink raw reply
* [PATCH] rev-list: omit duplicated parents.
From: Junio C Hamano @ 2006-01-29 23:30 UTC (permalink / raw)
To: Marco Costalba; +Cc: git, torvalds
In-Reply-To: <7vmzhekcz3.fsf@assigned-by-dhcp.cox.net>
Showing the same parent more than once for a commit does not
make much sense downstream, so stop it.
This can happen with an incorrectly made merge commit that
merges the same parent twice, but can happen in an otherwise
sane development history while squishing the history by taking
into account only commits that touch specified paths.
For example,
$ git rev-list --max-count=1 --parents addafaf -- rev-list.c
would have to show this commit ancestry graph:
.---o---.
/ \
.---*---o---.
/ 93b74bc \
---*---o---o-----o---o-----o addafaf
d8f6b34 \ /
.---o---o---.
\ /
.---*---.
3815f42
where 5 independent development tracks, only two of which have
changes in the specified paths since they forked. The last
change for the other three development tracks was done by the
same commit before they forked, and we were showing that three
times.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Junio C Hamano <junkio@cox.net> writes:
> I think it probably is a bug...
> ...
> Let me wait for a while to hear Linus contradicts me, though...
I've considered doing this only when path is specified, but
instead decided to do so for all commits. I recall there
are commits in the kernel archive created somehow with the
same parent listed twice, and the downstream tools would
have the same trouble if we didn't.
rev-list.c | 15 ++++++++++++++-
1 files changed, 14 insertions(+), 1 deletions(-)
d6d9f494403a4e77d17244ece43005eec51200d3
diff --git a/rev-list.c b/rev-list.c
index 0b142c1..93ea41b 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -12,6 +12,7 @@
#define COUNTED (1u << 2)
#define SHOWN (1u << 3)
#define TREECHANGE (1u << 4)
+#define TMP_MARK (1u << 5) /* for isolated cases; clean after use */
static const char rev_list_usage[] =
"git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
@@ -72,9 +73,21 @@ static void show_commit(struct commit *c
if (show_parents) {
struct commit_list *parents = commit->parents;
while (parents) {
- printf(" %s", sha1_to_hex(parents->item->object.sha1));
+ struct object *o = &(parents->item->object);
parents = parents->next;
+ if (o->flags & TMP_MARK)
+ continue;
+ printf(" %s", sha1_to_hex(o->sha1));
+ o->flags |= TMP_MARK;
}
+ /* TMP_MARK is a general purpose flag that can
+ * be used locally, but the user should clean
+ * things up after it is done with them.
+ */
+ for (parents = commit->parents;
+ parents;
+ parents = parents->next)
+ parents->item->object.flags &= ~TMP_MARK;
}
if (commit_format == CMIT_FMT_ONELINE)
putchar(' ');
--
1.1.5.g9843f
^ permalink raw reply related
* Re: [PATCH 0/3] Remove more parsers
From: Daniel Barkalow @ 2006-01-29 22:05 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vk6ciixv0.fsf@assigned-by-dhcp.cox.net>
On Sun, 29 Jan 2006, Junio C Hamano wrote:
> I do not have objections to git-tar-tree changes, but I am
> hesitant to use the tree parser in diff-tree due to its memory
> retention behaviour. We already use the commit parser in
> diff-tree but I think we currently do not ask for the tree part
> of the object to be parsed. I suspect this patch would badly
> interact with long-running "diff-tree --stdin", which is the
> workhorse of whatchanged. I haven't benched it though, and I'd
> be happy to see the impact is proven to be negligible.
I'll look into discarding the struct trees after use (since we're not
keeping flags on them, or storing references to them long-term), so we can
use the same parser without worse memory behavior. It does seem to take a
bunch more memory (and, oddly, be very slow) as I currently have it.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: git commit error on initial (the very first) commit
From: J. Bruce Fields @ 2006-01-29 21:51 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Andrey Borzenkov, git
In-Reply-To: <7v1wyqivx1.fsf@assigned-by-dhcp.cox.net>
On Sun, Jan 29, 2006 at 01:08:58PM -0800, Junio C Hamano wrote:
> In a freshly created repository, "git add ." would register
> everything to the index file, and a "git commit" with or without
> "-a" that immediately follows "git add ." would commit what is
> in the index. Use of "-a" would not make a difference here.
Aie, you're right of course, thanks.--b.
^ 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