* Re: CVS -> SVN -> Git
From: Eric S. Raymond @ 2007-07-14 19:52 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <4699034A.9090603@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu>:
> Martin Langhoff wrote:
> > On 7/14/07, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> >> Incidentally, now that cvs2svn 2.0.0 is nearly out, I am thinking about
> >> what it would take to write some other back ends for cvs2svn--turning
> >> it, essentially, into cvs2xxx. Most of the work that cvs2svn does is
> >> inferring the most plausible history of the repository from CVS's
> >> sketchy, incomplete, idiomatic, and often corrupt data. This work
> >> should also be useful for a cvs2git or cvs2hg or cvs2baz or ...
> >
> > Great to hear that. I'm game if we can do something in this direction
> > - surely we can make it talk to fastimport ;-)
>
> We added some hooks to cvs2svn 2.0 to start working in this direction.
Excuse me, I missed Michael's Haggerty's original post. But as it
happens I've been doing quite a lot of work with VCSes and migration
tools recently and I have some opinions and experience that I think are
relevant.
In slightly more detail: I just finished forward-porting sccs2rcs to
Python, I've been moving some Subversion-hosted stuff to Mercurial,
and I've been thinking about writing a simple rcs2svn because the last
time I tried using cvs2svn on a large RCS history (the Jargon File, as
it happens, a couple years back) it did a very poor job of coalescing
related commits without the CVS metadata. I'm going to hope 2.0.0 has
fixed that; I'll experiment and see.
Also, I'm in the process of rewriting Emacs VC mode and testing it
with three different VCSes. One consequence is that the Subversion
support in Emacs is going to cease sucking badly in the very near
future -- the VC-mode rewrite is giving VC mode the ability to make
atomic fileset commits if the underlying VCS will support them. I'm
putting the finishing touches on that code today, as it happens.
Another consequence is that Mercurial and git support will get really
good, oh, about ten minutes after the new Subversion backend lands.
The blocker on all three was the same weakness in the engine of VC
mode, for whicch I was (alas) responsible as its original author and
*which I have now fixed*.
So, I hear about plans to make cvs2svn generate something other than
Subversion, and here's my instant reaction:
DON'T DO IT!
This is not because I think Subversion is some kind of final answer to the
VCS problem. Fame from it -- I'm moving towards Mercurial. No, the
real reason I think this would be a waste of time is subtler than that.
Subversion, by design, is very good at capturing the metadata from
SCCS and RCS and the various CVS variants floating around. In fact,
lifting from those into Subversion is basically lossless - the real
problems are that (a) as Michael notes, the data you're losslessly
lifting is scratchy, and (b) as I've noted, you have to use heuristics
to coalesce file histories into changesets and those don't always make
the links they should.
That being the case, two-step conversion with tools that import CVS to
SVN and export from SVN to whatever actually works extremely well.
I'm speaking from direct recent experience here, not just theory. In
fact, it works so well well that I'm convinced a tool for direct
conversion from CVS to the third-generation systems would be misplaced
effort.
I'd much rather see the effort go into improving import to Subversion
from CVS and older, cruftier systems. Subversion is like the Heinlein quote
about low Earth orbit being halfway to anywhere -- once your code and
metadata are there, export to advanced alien VCSes is easy. So, Michael;
I know it's nice to think about building space probes that can go direct
to the aliens -- but please concentrate on building a better heavy-lift
vehicle, because low earth orbit is the hard part.
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Michael Haggerty @ 2007-07-14 20:01 UTC (permalink / raw)
To: Chris Shoemaker; +Cc: Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <20070714173223.GA25574@pe.Belkin>
Chris Shoemaker wrote:
> [...] I, for one, would be interested to know how
> cvs2svn's output compared to CVSps's, especially w.r.t. detecting each
> branch's parent.
The problem, as I'm sure you are aware, is that CVS does not record
unambiguously the parent of a branch. For example, the following two
situations are indistinguishable from the data stored in CVS:
1. Create BRANCH1 from trunk, then create BRANCH2 from BRANCH1 before
making any commits to BRANCH1
2. Create BRANCH1 from trunk, then create BRANCH2 from the same trunk
revision.
Older versions of cvs2svn would always create both branches from trunk.
cvs2svn 2.0 gathers statistics about the "possible parents" of each
symbol across multiple files. If BRANCH1 and BRANCH2 occur in another
file in a context that makes it clear that BRANCH2 was created from
BRANCH1 (i.e., because a revision was committed to BRANCH1 before
BRANCH2 was created), then it attempts to use BRANCH1 as the parent of
BRANCH2 in all files.
So yes, cvs2svn is somewhat intelligent about determining the correct
branch ancestry.
Michael
^ permalink raw reply
* Re: [PATCH 6/6] Add git-rewrite-commits
From: Sven Verdoolaege @ 2007-07-14 20:15 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Junio C Hamano
In-Reply-To: <Pine.LNX.4.64.0707141140510.14781@racer.site>
On Sat, Jul 14, 2007 at 01:49:59PM +0100, Johannes Schindelin wrote:
> Pooh. A lot of comments. Please take that as a sign that I am interested
Thanks. I'll look through them tomorrow.
> in rewrite-commits. BTW did I mention already that I like the name
> "rewrite-commits"?
You should like it. You suggested it.
(http://article.gmane.org/gmane.comp.version-control.git/45637)
Not that I had read that when I named it. I'm about 2.5 months
behind on my git mailing list reading.
skimo
^ permalink raw reply
* Exporting a tree from a repository
From: Ciprian Dorin Craciun @ 2007-07-14 20:25 UTC (permalink / raw)
To: git
Hello all!
I am a new GIT user, I like it, so I started playing with it for
different projects I work on.
Currently I am playing with "Linux from Scratch", and I have
written some scripts to automatize the build process -- kind of
install scripts...
For this I use GIT to store all the source packages -- each inside
it's own branch :).
My question is the following: How can I export an entire tree
without using a working directory, or cloning the repository. (Because
from what I have seen so far there is no way to use the same
repository with many working directories...)
Now I know that I can use "git archive | tar -x"... I am looking
for the same functionality but without the intermediary file... Maybe
something like "git archive --format=tree <branch>"...
Also there is also a possible drawback by using git archive with
tar format, that is if I decide to make the repository available to
the public then it would be nice to have this export functionality...
I think this could be also used for kernel sources as an alternative
to downloading the tar.bz2 file or copying the entire tree...
Thank you all for your feedback!
Ciprian Craciun.
^ permalink raw reply
* Re: Confusing language in man page
From: Satyam Sharma @ 2007-07-14 20:27 UTC (permalink / raw)
To: git
In-Reply-To: <a781481a0707141108g4664a627w94e0d21c3629cb49@mail.gmail.com>
On 7/14/07, Satyam Sharma <satyam.sharma@gmail.com> wrote:
> Hi,
>
> [ I'm using Fedora's latest package. ]
I should probably clarify:
$ git --version
git version 1.5.0.6
Perhaps man pages / functionality have been updated significantly
since that, so let me know if that's the case.
> From git-checkout(1) and git-branch(1):
>
> -l Create the new branch's ref log. This activates recording of
> all changes to made the
> branch ref, enabling use of date
>
> I'd be glad if someone could explain that a bit more verbosely
> in the man page
> (or just here in a reply), or at least make that grammatically
> correct/readable :-)
Ok, another confusion I hit (as I learn more about git) tonight:
* What exactly is the use of git-diff's "-p" option?
$ git diff
and
$ git diff -p
produce the same output / do the same thing -- the man page mentions
"Generate patch (see section on generating patches)" but I couldn't find
said section (is that referring to some other man page?)
* On my system, doing:
$ git diff
with no outstanding changes in my current working tree produces some
bogus newlines, throwing the prompt to the bottom of the xterm window.
This sounds like weird / undesirable behaviour and I have a feeling must
already be fixed in latest git (?)
Thanks,
Satyam
^ permalink raw reply
* Re: git-svn: tagging trunk in SVN with git-svn?
From: Eric Wong @ 2007-07-14 20:35 UTC (permalink / raw)
To: git discussion list
In-Reply-To: <20070714140359.GA5738@piper.oerlikon.madduck.net>
martin f krafft <madduck@madduck.net> wrote:
> Dear list,
>
> I searched the list(s) and even read the code of git-svn, but I am
> none the wiser now. From what I understand, git-svn is primarily
> used to interact with subversion, rather than doing one-shot imports
> (which it can do as well).
>
> I am using it now and it works like a charm (thanks!). However,
> I cannot really figure out how to tag the remote trunk from within
> git-svn. I tried `git tag tags/1.2.57`, `git tag 1.2.57` and `git
> branch tags/1.2.57`, but in none of the three cases does dcommit
> think that it needs to push anything upstream.
>
> Is what I am trying to do possible, or do I need to use svn for
> that?
git-svn doesn't currently know how to create new tags/patches. It's
been requested but I haven't had much time or desire to implement it,
patches accepted :)
I just use "svn cp url1 url2", but I agree having git-svn automatically
know about that branch would be nice.
--
Eric Wong
^ permalink raw reply
* Re: [PATCH] git-svn init/clone --stdlayout option to default-init trunk/tags/branches
From: Eric Wong @ 2007-07-14 20:38 UTC (permalink / raw)
To: git
In-Reply-To: <20070714120450.GA21890@piper.oerlikon.madduck.net>
martin f krafft <madduck@madduck.net> wrote:
> also sprach Eric Wong <normalperson@yhbt.net> [2007.07.14.1334 +0200]:
> > I have highlighting search set in my editor (vim :set hls)
> > and usually just search for spaces vs tabs to make sure I'm clean.
>
> Try:
>
> :se lcs=tab:>-,trail,-
That didn't work, this does:
:se lcs=tab:>-,trail:-
> augroup listinsert
> autocmd InsertEnter * set nolist
> autocmd InsertLeave * set list
> augroup end
Eep. Too confusing ;) I have my hls color set to be a red underscore
(which nothing else in my syntax higlighting uses), so it's less
intrusive for me.
> > Of course, maintaining a consistent whitespace style helps a *lot*
> > with the git/Linux patch exchange development style because it
> > avoids needless patch application conflicts that arise from
> > whitespace differences.
>
> Using tabs also makes it impossible to X-cut-paste patches from
> emails; you *have* to use git-am and/or a temporary file, which
> i don't like at all.
Ah. I that's one of the reasons I rarely use X-cut-paste for multi-line
strings.
When I apply patches with or without git-am from email, I just start
mutt inside the working source directory I'm in, and from the mutt index
I spawn vim to edit any email (just hit 'e'), go into visual mode,
select the part I want to apply and pipe that to whatever patch
application program I want to use, and :q! out of vim.
--
Eric Wong
^ permalink raw reply
* Re: [PATCH] Add --show-size to git log to print message size
From: Marco Costalba @ 2007-07-14 20:46 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
In-Reply-To: <7vodiehko7.fsf@assigned-by-dhcp.cox.net>
On 7/14/07, Junio C Hamano <gitster@pobox.com> wrote:
>
> "size" is a bit vague here. What if we later want to extend
> things so that you can ask for the entire log entry size
> including the patch output part (I am not saying that would be
> an easy change --- I am more worried about the stability of the
> external interface). So is --show-"size". "message-size" would
> have been a bit easier to swallow, but I sense the problem runs
> deeper.
What about --section-sizes?
You can add in the output line all the sizes you want, message, patch
and future extensions separated by a space. An example output for
message and patch sizes.
sizes 456 565\n
Or, as a stream friendly alternative (and also more elegant) you can
output 'section size' before each section, so as example
commit d9e940....
section size 456
< log header and message body>
section size 565
<patch diff content>
section size 232
<other type of content>
> I have a more basic question. If you are reading from non "-p"
> output, where do you exactly have the wasted cycles in your
> reader's processing?
qgit loading works like this:
git log output is read as a series of big binary chunks by a Qt
library function that calls read(), these chunks are read each one in
a different buffer and there they stay for all the application life
time (or until a data refresh), so there is no copy of data in qgit,
the buffers are allocated and the pointers passed to read(), that's
all.
It's a kind of software DMA ;-)
The only information that qgit needs to infere at startup is where to
find the first line of each commit, for parent information and
revision's counting, all the other data is read and consumed only on
demand, i.e. for showing to user, but because only the screen visible
part of the list is needed, data is read from these buffers and parsed
*in small chunks* and only when user scrolls the view.
The problem is that to get the first line of each revision the message
boundaries of _all_ the commits must be known/found.
Because currently there is no message size information the application have to:
-get the offset of commit first line
-try to find the delimiting '\0' if existing (binary chunks could be
truncated at any point)
-get the offset of commit first line of next revision
-and so on for all the revisions
Finding the delimiting '\0' it means to loop across the whole buffers
and _this_ is the expensive and not needed part. If just after the
first line would be possible to point to the beginning of the next
revision this seeking for '\0' would be not necessary anymore.
When user asks for data of revision 'x' then because offset of
revision 'x' is known, application could just point to the correct
offset in the correct data buffer and parse out the (small) needed
info.
Hope I have explained clearly enough, I have some problems writing in
at late evening ;-)
Marco
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Junio C Hamano @ 2007-07-14 20:58 UTC (permalink / raw)
To: esr; +Cc: Michael Haggerty, Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <20070714195252.GB11010@thyrsus.com>
esr@thyrsus.com (Eric S. Raymond) writes:
> So, I hear about plans to make cvs2svn generate something other than
> Subversion, and here's my instant reaction:
>
> DON'T DO IT!
>
> This is not because I think Subversion is some kind of final answer to the
> VCS problem. Fame from it -- I'm moving towards Mercurial. No, the
> real reason I think this would be a waste of time is subtler than that.
>
> Subversion, by design, is very good at capturing the metadata from
> SCCS and RCS and the various CVS variants floating around. In fact,
> lifting from those into Subversion is basically lossless - the real
> problems are that (a) as Michael notes, the data you're losslessly
> lifting is scratchy, and (b) as I've noted, you have to use heuristics
> to coalesce file histories into changesets and those don't always make
> the links they should.
Converting to Subversion might be lossless, but is it really the
most convenient intermediate format for other people to convert
further from?
Even after xxx2svn overcomes the problems (a) and (b) you noted
above, my impression has been that svn2yyy needs to work harder
than necessary to grok the branches/ and tags/ that artificially
are flattened, only because Subversion does not do branches nor
tags, but just represents them as copies.
^ permalink raw reply
* Re: Exporting a tree from a repository
From: Julian Phillips @ 2007-07-14 21:46 UTC (permalink / raw)
To: Ciprian Dorin Craciun; +Cc: git
In-Reply-To: <8e04b5820707141325o400e170bu9eb80b304cae506b@mail.gmail.com>
On Sat, 14 Jul 2007, Ciprian Dorin Craciun wrote:
> Hello all!
>
> I am a new GIT user, I like it, so I started playing with it for
> different projects I work on.
>
> Currently I am playing with "Linux from Scratch", and I have
> written some scripts to automatize the build process -- kind of
> install scripts...
>
> For this I use GIT to store all the source packages -- each inside
> it's own branch :).
>
> My question is the following: How can I export an entire tree
> without using a working directory, or cloning the repository. (Because
> from what I have seen so far there is no way to use the same
> repository with many working directories...)
You can have as many working directories as you want from one repository
using the git-new-workdir script from contrib/workdir. You do need to be
careful when updating references though (you basically want to avoid
updating a reference that you are using in another working directory).
You should also be able to use this to get an "export" - simply create the
new workdir and then remove the .git (being careful not to accidentally do
this in your actual repository). However I expect there is a better way
to do this ...
--
Julian
---
Quark! Quark! Beware the quantum duck!
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Oswald Buddenhagen @ 2007-07-14 21:50 UTC (permalink / raw)
To: Eric S. Raymond; +Cc: Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <20070714195252.GB11010@thyrsus.com>
On Sat, Jul 14, 2007 at 03:52:52PM -0400, Eric S. Raymond wrote:
> That being the case, two-step conversion with tools that import CVS to
> SVN and export from SVN to whatever actually works extremely well.
>
well, yes. hoooowever ... you are missing a few details:
- conversion time. until we have incremental conversions, this is
absolutely critical to many organizations.
- psychology. cvs2xxx is simpler than cvs2svn + svn2xxx. it's also sort
of a mindset thing. don't underestimate this.
--
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!
--
Chaos, panic, and disorder - my work here is done.
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Michael Haggerty @ 2007-07-14 22:19 UTC (permalink / raw)
To: esr; +Cc: Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <20070714195252.GB11010@thyrsus.com>
Eric S. Raymond wrote:
> In slightly more detail: I just finished forward-porting sccs2rcs to
> Python, I've been moving some Subversion-hosted stuff to Mercurial,
> and I've been thinking about writing a simple rcs2svn because the last
> time I tried using cvs2svn on a large RCS history (the Jargon File, as
> it happens, a couple years back) it did a very poor job of coalescing
> related commits without the CVS metadata. I'm going to hope 2.0.0 has
> fixed that; I'll experiment and see.
Could you give a quick summary of the relevant differences between CVS
and RCS files in this context? Then I'd be happy to try to figure out
how bad the situation still is today, and whether it can be easily improved.
> [...]
> So, I hear about plans to make cvs2svn generate something other than
> Subversion, and here's my instant reaction:
>
> DON'T DO IT!
>
> This is not because I think Subversion is some kind of final answer to the
> VCS problem. Fame from it -- I'm moving towards Mercurial. No, the
> real reason I think this would be a waste of time is subtler than that.
>
> Subversion, by design, is very good at capturing the metadata from
> SCCS and RCS and the various CVS variants floating around. In fact,
> lifting from those into Subversion is basically lossless - the real
> problems are that (a) as Michael notes, the data you're losslessly
> lifting is scratchy, and (b) as I've noted, you have to use heuristics
> to coalesce file histories into changesets and those don't always make
> the links they should.
>
> That being the case, two-step conversion with tools that import CVS to
> SVN and export from SVN to whatever actually works extremely well.
Other people have complained about having to convert from SVN to
distributed SCMs, because the SVN model doesn't map so easily to their
favorite.
You are basically suggesting that an SVN repository is the best lingua
franca of the SCM world, which I don't believe. The CVS history *does*
have to be deformed a bit to fit into SVN, and an svn2xxx converter
would have to undo the deformation.
My idea is not to built (for example) cvs2git; rather, I'd like cvs2svn
to be split conceptually into two tools:
cvs2<abstract_description_of_cvs_history>, whose job it is to determine
the most likely "true" CVS history based on the data stored in the CVS
repository, and
<abstract_description_of_cvs_history>2svn
Then later write
<abstract_description_of_cvs_history>2git
<abstract_description_of_cvs_history>2hg
etc.
The first split is partly done in cvs2svn 2.0. And I naively imagine
that writing the new output back ends won't be all that much work.
Michael
^ permalink raw reply
* Re: mtimes of working files
From: Jan Hudec @ 2007-07-14 22:22 UTC (permalink / raw)
To: David Woodhouse
Cc: Linus Torvalds, Theodore Tso, Andy Parkins, git,
Johannes Schindelin
In-Reply-To: <1184370414.2785.79.camel@shinybook.infradead.org>
[-- Attachment #1: Type: text/plain, Size: 3589 bytes --]
On Sat, Jul 14, 2007 at 00:46:54 +0100, David Woodhouse wrote:
> On the occasions I actually try to _use_ branches, I find it very
> suboptimal. Perhaps it's just because I'm stupid. I'm sure that's why I
> ended up committing changes to the wrong branch. But having to rebuild
> (even with ccache) after changing branches is a PITA. Just changing
> branches at all is a PITA if you have uncommitted changes (which I
> usually do because I've usually tested _some_ random patch in a build
> tree for the hardware which is closest to hand). Pulling a whole bunch
> of unwanted changes on the 'development' branch while on GPRS, when all
> I really needed was a single commit from the 'stable' branch also didn't
> amuse me, although I'm sure if I had the time to play with it I'd have
> been able to avoid that.
I have to say it's the exact oposite for me. I used to have branches checked
out separately, with arch and than bzr, and I find the git way much easier in
the end. Exactly because I don't need the multiple checkouts. Often, each of
them needed to contain some local stuff (like test data or some configuration
for building) and rebuilding in one of them does not help the others (usually
they are very close to each other).
For uncommited changes, git makes it possible (yes, I agree it is an extra
command one might want to avoid) to commit them and them uncommit or amend
the commit when you get back to them.
Pulling something into the wrong place can happen quite as likely, at least
to me, with separate checkouts as with switching in one place. And than git
actually makes it much easier to fix it when you are in a single tree. Until
you publish, you git allows fixing anything with commit --amend and/or reset.
> I can, and do, mirror stuff from all kinds of suboptimal version control
> systems into single-branch git trees. And I include multi-branched git
> trees in my definition of 'suboptimal'. My ability to do that doesn't
> really help the newbies who are expected with branches, though.
For newbies, the bzr approach is much easier to grasp, even though I really
find that the git one is actually a little nicer to work with.
> I just wish people would make stuff available on the _servers_ in
> separate trees rather than in branches -- if some people prefer branches
> locally then that's their option; at the moment we kind of force people
> into it. They _could_ avoid it but they'd have to know what they're
> doing.
You can treat the servers as separate trees! When cloning and/or pulling, you
can set up to pull just the one branch you are interested in. Having them as
separate trees would either be inefficient (the data would not be shared), or
would bring it's own class of problems.
I would like, if git could have something like "checkouts". The idea is, that
a checkout would contain the working tree, .git/HEAD saying what revision it
is at and .git/index and everything else would be linked from the repository
it is checked out from. That would allow you to have different branches
checked out at different places, while not only sharing all the data, but
also all of them available in all the checkouts and commands like pull
updating it in all of them.
It would be IMHO possible to symlink all the stuff in .git except HEAD and
index, except for one problem. This is if you have two checkouts from the
same branch and check out of them, the other one needs to know, that it's
head should now be detached to stay where it was.
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: mtimes of working files
From: Julian Phillips @ 2007-07-14 22:36 UTC (permalink / raw)
To: Jan Hudec
Cc: David Woodhouse, Linus Torvalds, Theodore Tso, Andy Parkins, git,
Johannes Schindelin
In-Reply-To: <20070714222221.GB3678@efreet.light.src>
On Sun, 15 Jul 2007, Jan Hudec wrote:
> I would like, if git could have something like "checkouts". The idea is, that
> a checkout would contain the working tree, .git/HEAD saying what revision it
> is at and .git/index and everything else would be linked from the repository
> it is checked out from. That would allow you to have different branches
> checked out at different places, while not only sharing all the data, but
> also all of them available in all the checkouts and commands like pull
> updating it in all of them.
>
> It would be IMHO possible to symlink all the stuff in .git except HEAD and
> index, except for one problem. This is if you have two checkouts from the
> same branch and check out of them, the other one needs to know, that it's
> head should now be detached to stay where it was.
You basically just described what the git-new-workdir script in
contrib/workdir does ... it doesn't address the issue of reference
updating.
--
Julian
---
Most people's favorite way to end a game is by winning.
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Karl Fogel @ 2007-07-14 22:44 UTC (permalink / raw)
To: Michael Haggerty; +Cc: esr, Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <46994BDF.6050803@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu> writes:
> My idea is not to built (for example) cvs2git; rather, I'd like cvs2svn
> to be split conceptually into two tools:
>
> cvs2<abstract_description_of_cvs_history>, whose job it is to determine
> the most likely "true" CVS history based on the data stored in the CVS
> repository, and
>
> <abstract_description_of_cvs_history>2svn
>
> Then later write
>
> <abstract_description_of_cvs_history>2git
> <abstract_description_of_cvs_history>2hg
>
> etc.
>
> The first split is partly done in cvs2svn 2.0. And I naively imagine
> that writing the new output back ends won't be all that much work.
I think an intermediate interchange format is the right way to go.
But, isn't this what VCP / RevML is all about? Perhaps RevML is
already suited to be that interchange format... (Haven't looked at it
in detail, just pointing out that there has at least been an attempt
to reinvent this wheel already :-) ).
-Karl
^ permalink raw reply
* Mistake in manpage for git-commit-tree?
From: Geoff Richards @ 2007-07-14 22:47 UTC (permalink / raw)
To: git
Hi,
Just saw this in Documentation/git-commit-tree.txt at line 75:
A commit comment is read from stdin (max 999 chars). If a changelog
But from looking at the code it appears there is no such limit. That's
the size of the buffer used to read the commit message in, but it should
read multiple chunks of that size if you give it more than that.
If I'm not missing something, I'd suggest removing that bit in parens.
hth,
Geoff
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: David Frech @ 2007-07-14 23:23 UTC (permalink / raw)
To: Michael Haggerty; +Cc: esr, Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <46994BDF.6050803@alum.mit.edu>
Now that this party is really rollicking, I think I'll join in. ;-)
I have a modest svn repo (about 800 commits) that contains fifteen or
so small projects. It started life as a CVS repo, and as the projects
grew and changed, and as I learned more about CVS, things got moved
around. Later, when I got interested in svn (in 2005) I converted the
repo, using cvs2svn. It got a few things wrong - mostly, that it
thought there was one project in the repo, and created toplevel
trunk/, branches/, and tags/ directories, and lumped everything below
these.
So, in svn, I moved things around some more.
Now I want to switch to git. I've since added enough to svn that there
is no option but to use th svn repo as my source. git-svnimport
doesn't work for me because its idea of the structure of my repo is
too limited. I looked around, stumbled over fast-import, and got
hooked on the idea of using it. It seemed simple enough... I wrote a
350-line Lua (!!) program that parses the svn dump file and creates a
commit stream for fast-import.
It took a day and half to get the svn dump parsing right (it's an
egregiously bad format) but only a couple of hours to write the
fast-import backend.
The code "works" in the sense that it can read an svn dump and create
a git repo that looks reasonable, but it misses a few things, like
properly inferring branch creation from the "copyfrom" info in the svn
dump.
However, it's fairly fast (~35 commits/sec) and flexible. I want to,
in the process of doing this conversion, "canonicalize" the structure
of the repo and throw away all the commits from cvs and svn that just
moved things around. This poses another inference challenge, but
having a modest simple tool (ie, a short enough program to easily
understand and modify) helps.
Having done all this, I realized that this is a good way to go.
Separating, as Michael suggests, the "parsing" part from the "commit
generating" part, not only makes the tools easier to write, but makes
them more flexible. If hg or bzr had a git-like fast-import (maybe
they do) it would take me about 35 minutes to target that instead. And
in the process I came across some "missing features" in fast-import,
which Shawn Pearce was able to quickly add.
My repo is tiny, but I still think that speed and flexibility are key
in this process. If I can write a little script that can be useful to
someone with 100k commits instead of my measly 800, that's great.
For that matter, fast-import is a fairly short program. It wouldn't be
hard for other scm projects to do something similar. fast-import could
become a "standard" intermediate format. But even if that doesn't
happen, the amounts of code we're talking about (to do parsing and
commit generation) are reasonably modest and easy to change.
As soon as I make a bit more progress I'm going to make my code available.
Cheers,
- David
On 7/14/07, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> My idea is not to built (for example) cvs2git; rather, I'd like cvs2svn
> to be split conceptually into two tools:
>
> cvs2<abstract_description_of_cvs_history>, whose job it is to determine
> the most likely "true" CVS history based on the data stored in the CVS
> repository, and
>
> <abstract_description_of_cvs_history>2svn
>
> Then later write
>
> <abstract_description_of_cvs_history>2git
> <abstract_description_of_cvs_history>2hg
>
> etc.
>
> The first split is partly done in cvs2svn 2.0. And I naively imagine
> that writing the new output back ends won't be all that much work.
>
> Michael
>
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
If I have not seen farther, it is because I have stood in the
footsteps of giants.
^ permalink raw reply
* [PATCH] Make every builtin-*.c file #include "builtin.h"
From: Peter Hagervall @ 2007-07-14 23:14 UTC (permalink / raw)
To: junkio; +Cc: git
Make every builtin-*.c file #include "builtin.h".
Also takes care of some declaration/definition mismatches.
Signed-off-by: Peter Hagervall <hager@cs.umu.se>
---
builtin-bundle.c | 1 +
builtin-checkout-index.c | 1 +
builtin-fetch--tool.c | 1 +
builtin-for-each-ref.c | 3 ++-
builtin-fsck.c | 3 ++-
builtin-gc.c | 1 +
builtin-merge-base.c | 1 +
builtin-merge-file.c | 7 ++++---
builtin-pack-refs.c | 1 +
builtin-rerere.c | 1 +
builtin-runstatus.c | 1 +
builtin-show-ref.c | 1 +
12 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/builtin-bundle.c b/builtin-bundle.c
index 306ad29..6ae5ab0 100644
--- a/builtin-bundle.c
+++ b/builtin-bundle.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "object.h"
#include "commit.h"
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 8460f97..75377b9 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -36,6 +36,7 @@
* of "-a" causing problems (not possible in the above example,
* but get used to it in scripting!).
*/
+#include "builtin.h"
#include "cache.h"
#include "strbuf.h"
#include "quote.h"
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index ed4d5de..e2f8ede 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "commit.h"
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index 2b21842..0afa1c5 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
@@ -796,7 +797,7 @@ static struct ref_sort *default_sort(void)
return sort;
}
-int cmd_for_each_ref(int ac, const char **av, char *prefix)
+int cmd_for_each_ref(int ac, const char **av, const char *prefix)
{
int i, num_refs;
const char *format = NULL;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index a6ef65e..350ec5e 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "commit.h"
#include "tree.h"
@@ -659,7 +660,7 @@ static const char fsck_usage[] =
"git-fsck [--tags] [--root] [[--unreachable] [--cache] [--full] "
"[--strict] [--verbose] <head-sha1>*]";
-int cmd_fsck(int argc, char **argv, const char *prefix)
+int cmd_fsck(int argc, const char **argv, const char *prefix)
{
int i, heads;
diff --git a/builtin-gc.c b/builtin-gc.c
index 45025fb..9397482 100644
--- a/builtin-gc.c
+++ b/builtin-gc.c
@@ -10,6 +10,7 @@
* Copyright (c) 2006 Shawn O. Pearce
*/
+#include "builtin.h"
#include "cache.h"
#include "run-command.h"
diff --git a/builtin-merge-base.c b/builtin-merge-base.c
index e35d362..0108e22 100644
--- a/builtin-merge-base.c
+++ b/builtin-merge-base.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "commit.h"
diff --git a/builtin-merge-file.c b/builtin-merge-file.c
index 10ec63b..58deb62 100644
--- a/builtin-merge-file.c
+++ b/builtin-merge-file.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "xdiff/xdiff.h"
#include "xdiff-interface.h"
@@ -5,9 +6,9 @@
static const char merge_file_usage[] =
"git merge-file [-p | --stdout] [-q | --quiet] [-L name1 [-L orig [-L name2]]] file1 orig_file file2";
-int cmd_merge_file(int argc, char **argv, char **envp)
+int cmd_merge_file(int argc, const char **argv, const char *prefix)
{
- char *names[3];
+ const char *names[3];
mmfile_t mmfs[3];
mmbuffer_t result = {NULL, 0};
xpparam_t xpp = {XDF_NEED_MINIMAL};
@@ -51,7 +52,7 @@ int cmd_merge_file(int argc, char **argv, char **envp)
free(mmfs[i].ptr);
if (ret >= 0) {
- char *filename = argv[1];
+ const char *filename = argv[1];
FILE *f = to_stdout ? stdout : fopen(filename, "wb");
if (!f)
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index 7584992..09df4e1 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
diff --git a/builtin-rerere.c b/builtin-rerere.c
index 6ffc43d..29d057c 100644
--- a/builtin-rerere.c
+++ b/builtin-rerere.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "path-list.h"
#include "xdiff/xdiff.h"
diff --git a/builtin-runstatus.c b/builtin-runstatus.c
index 4b489b1..2db25c8 100644
--- a/builtin-runstatus.c
+++ b/builtin-runstatus.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "wt-status.h"
diff --git a/builtin-show-ref.c b/builtin-show-ref.c
index 9463ff0..65051d1 100644
--- a/builtin-show-ref.c
+++ b/builtin-show-ref.c
@@ -1,3 +1,4 @@
+#include "builtin.h"
#include "cache.h"
#include "refs.h"
#include "object.h"
--
1.5.3.GIT
^ permalink raw reply related
* Re: [PATCH] git-reset: allow --soft in a bare repo
From: Jeff King @ 2007-07-15 1:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v7ip3jsf8.fsf@assigned-by-dhcp.cox.net>
On Sat, Jul 14, 2007 at 01:33:31AM -0700, Junio C Hamano wrote:
> > since git-branch is usually used for _making_ a branch, whereas
> "branch -f" is very often used to "reset the branch tip". My
> git day typically begins with "branch -f pu next".
I think we just have a different perspective of what is "usual" here.
> Actually, after thinking about this a bit more, I have become
> somewhat reluctant, as this might confuse new users by giving
> them a wrong mental model of what "reset" is about.
OK, as I said on irc, I don't think this is a huge issue in the first
place, and your argument about encouraging a particular workflow for
git-reset makes some sense (even if that hasn't been my approach to
git-reset in the past).
-Peff
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Eric S. Raymond @ 2007-07-15 1:39 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <46994BDF.6050803@alum.mit.edu>
Michael Haggerty <mhagger@alum.mit.edu>:
> Could you give a quick summary of the relevant differences between CVS
> and RCS files in this context? Then I'd be happy to try to figure out
> how bad the situation still is today, and whether it can be easily improved.
I found my copy of the bug report, and I misremembered the problem
slightly. It turns out to be even more relevant to this
discussion than I thought.
Thread begins with <20040810031409.GA25564@thyrsus.com> on
9 Aug 2004. The thread title was "RFC -- enhancing cvs2svn to have a
notion of spans of mergeable commits". Your mailing-list archive
search can't seem to find it, unfortunately. I'll repost the query
iseparately
> Other people have complained about having to convert from SVN to
> distributed SCMs, because the SVN model doesn't map so easily to their
> favorite.
OK. But I think that if SVN -> X is hard, CVS -> X is going to be harder.
> You are basically suggesting that an SVN repository is the best lingua
> franca of the SCM world, which I don't believe.
Not quite. I'm suggesting it's an appropriate lingua franca for centralized
VCSes with branching, e.g. everything pre-Arch.
> The CVS history *does*
> have to be deformed a bit to fit into SVN, and an svn2xxx converter
> would have to undo the deformation.
Then perhaps the right thing to think about is this: how exactly does
CVS history need to be deformed, and is there some way to express the
lost information as conventional properties or tags?
> My idea is not to built (for example) cvs2git; rather, I'd like cvs2svn
> to be split conceptually into two tools:
Well, that makes more sense. But how would whatever the first half outputs
be different from an svn dump file?
--
<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>
^ permalink raw reply
* Re: mtimes of working files
From: Daniel Barkalow @ 2007-07-15 1:46 UTC (permalink / raw)
To: Julian Phillips
Cc: Jan Hudec, David Woodhouse, Linus Torvalds, Theodore Tso,
Andy Parkins, git, Johannes Schindelin
In-Reply-To: <Pine.LNX.4.64.0707142331380.14090@beast.quantumfyre.co.uk>
On Sat, 14 Jul 2007, Julian Phillips wrote:
> On Sun, 15 Jul 2007, Jan Hudec wrote:
>
> > It would be IMHO possible to symlink all the stuff in .git except HEAD and
> > index, except for one problem. This is if you have two checkouts from the
> > same branch and check out of them, the other one needs to know, that it's
> > head should now be detached to stay where it was.
>
> You basically just described what the git-new-workdir script in
> contrib/workdir does ... it doesn't address the issue of reference updating.
That's where keeping the index's parents in the index would help. Various
people have implemented it at various times, but it's never quite become
sufficiently important to people to have the correct behavior worked out
and put into mainline. IIRC, not too long ago Junio had an implementation
in pu, but ended up dropping it because almost nobody would see a difference,
and the people who did see a difference only had it interfere with what
they were trying to do.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Shawn O. Pearce @ 2007-07-15 2:22 UTC (permalink / raw)
To: Steffen Prohaska
Cc: Michael Haggerty, Simon Hausmann, Martin Langhoff,
Julian Phillips, Git Mailing List, dev
In-Reply-To: <EC3B307E-EA83-4128-BABD-D9BDB78F987E@zib.de>
Steffen Prohaska <prohaska@zib.de> wrote:
> On Jul 14, 2007, at 7:09 PM, Michael Haggerty wrote:
> >Martin Langhoff wrote:
> >>On 7/14/07, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> >>>Incidentally, now that cvs2svn 2.0.0 is nearly out, I am thinking
> >>>about
> >>>what it would take to write some other back ends for cvs2svn--
> >>>turning
> >>>it, essentially, into cvs2xxx. Most of the work that cvs2svn
...
> >>
> >>Great to hear that. I'm game if we can do something in this direction
> >>- surely we can make it talk to fastimport ;-)
> >
> >We added some hooks to cvs2svn 2.0 to start working in this direction.
> >But I don't really know what information is needed for a git import.
> >One quick-and-dirty idea that I had was to have cvs2svn output
> >information compatible with cvsps's output, as I believe that several
> >tools rely on cvsps to do the dirty work and so could perhaps be
> >persuaded to use cvs2svn out of the box.
>
> From my understanding, piping data to git fast-import would be
> a sane gateway to git. The input format of fast-import is document
> in [1].
>
> Maybe Shaw Pearce has some comments on that. Shawn did most
> (maybe all) of the work on git-fast-import.
You must be new to this discussion. ;-)
git-fast-import started as a backend for a hacked up version of
cvs2svn that Jon Smirl was working on to convert the massive Mozilla
CVS repository into Git. Jon started from the cvs2svn codebase
because it best handled the damaged RCS files that exist in the
Mozilla repository. Many emails have been exchanged between myself,
Michael and Jon on this subject.
So yes, git-fast-import was designed to act as a backend behind
something like cvs2xxx. Some of the "oddities" of the fast-import
input language are the way they are partly because of the way
the (older) cvs2svn code generated output in SVN dump format.
Certain data was available at certain times and not at others,
so Jon wanted to feed it to git-fast-import when he had it, rather
than needing to buffer it or rearrange code.
I'm staying far away from writing fast-import frontends. Anyone that
wants/needs a CVS frontend is welcome to implement one, but it
won't written be me. I gave up CVS a long time ago and will never
return to it. My only VCS is Git, and converting Git->Git is sort
of stupid. So I have no need for a fast-import frontend.
But I do maintain fast-import. Well over 99% of it was written
by me. ;-)
--
Shawn.
^ permalink raw reply
* Re: CVS -> SVN -> Git
From: Shawn O. Pearce @ 2007-07-15 2:30 UTC (permalink / raw)
To: David Frech
Cc: Michael Haggerty, esr, Martin Langhoff, Julian Phillips, git, dev
In-Reply-To: <7154c5c60707141623s3f70e967s226e5da29965a173@mail.gmail.com>
David Frech <david@nimblemachines.com> wrote:
> Now I want to switch to git. I've since added enough to svn that there
> is no option but to use th svn repo as my source. git-svnimport
> doesn't work for me because its idea of the structure of my repo is
> too limited. I looked around, stumbled over fast-import, and got
> hooked on the idea of using it. It seemed simple enough... I wrote a
> 350-line Lua (!!) program that parses the svn dump file and creates a
> commit stream for fast-import.
>
> It took a day and half to get the svn dump parsing right (it's an
> egregiously bad format) but only a couple of hours to write the
> fast-import backend.
With the 'C' (copy) and 'R' (rename) operators in fast-import I was
starting to suspect that an SVN dump->fast-import stream translator
wasn't going to be that complex.
I wouldn't want to attempt to parse the SVN dump format directly
in fast-import. As you said the format is horribly difficult
to read. The entire fast-import stream parser is only 624 lines
of C (the other 1,636 lines of fast-import are for documentation,
the in memory tree/branch management and packfile generation).
I doubt the SVN dump file can be parsed in as few lines of C code.
--
Shawn.
^ permalink raw reply
* Re: [PATCH] Fix git-p4 on Windows to not use the Posix sysconf
From: Shawn O. Pearce @ 2007-07-15 2:49 UTC (permalink / raw)
To: Simon Hausmann; +Cc: Alex Riesen, Marius Storm-Olsen, git, Junio C Hamano
In-Reply-To: <200707131533.55544.simon@lst.de>
Simon Hausmann <simon@lst.de> wrote:
> On Friday 13 July 2007 15:03:51 Alex Riesen wrote:
> > On 7/13/07, Marius Storm-Olsen <marius@trolltech.com> wrote:
> > > argmax = min(4000, os.sysconf('SC_ARG_MAX'))
> >
> > I wonder why the code in question does not use "-x"?
> > I use it git-p4-import and haven't seen the limit yet.
>
> I still think the patch makes sense as stop-gap for 1.5.3 though, because
> without it git-p4 doesn't work at all on Windows.
Thanks. Marius' patch was whitespace damaged in the context lines,
but it was easily repaired. I've got a couple of other small items
in my fastimport repository that I'm going to ask Junio to include
in 1.5.3 shortly.
--
Shawn.
^ permalink raw reply
* [PATCH] Teach fast-import to recursively copy files/directories
From: Shawn O. Pearce @ 2007-07-15 5:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Some source material (e.g. Subversion dump files) perform directory
renames by telling us the directory was copied, then deleted in the
same revision. This makes it difficult for a frontend to convert
such data formats to a fast-import stream, as all the frontend has
on hand is "Copy a/ to b/; Delete a/" with no details about what
files are in a/, unless the frontend also kept track of all files.
The new 'C' subcommand within a commit allows the frontend to make a
recursive copy of one path to another path within the branch, without
needing to keep track of the individual file paths. The metadata
copy is performed in memory efficiently, but is implemented as a
copy-immediately operation, rather than copy-on-write.
With this new 'C' subcommand frontends could obviously implement an
'R' (rename) on their own as a combination of 'C' and 'D' (delete),
but since we have already offered up 'R' in the past and it is a
trivial thing to keep implemented I'm not going to deprecate it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
This and the following changes since commit 9d6f220cc8ffbd71b4c68765b52c3a7c41dd729b:
Josh Triplett (1):
Remove useless uses of cat, and replace with filename arguments
are available in the git repository at:
repo.or.cz:/srv/git/git/fastimport.git master
Marius Storm-Olsen (1):
Fix git-p4 on Windows to not use the Posix sysconf function.
Shawn O. Pearce (2):
Correct trivial typo in fast-import documentation
Teach fast-import to recursively copy files/directories
Documentation/git-fast-import.txt | 40 +++++++++++++++--
contrib/fast-import/git-p4 | 6 ++-
fast-import.c | 81 ++++++++++++++++++++++++++++++++++--
t/t9300-fast-import.sh | 83 +++++++++++++++++++++++++++++++++++++
4 files changed, 200 insertions(+), 10 deletions(-)
Hopefully this stuff will make it into 1.5.3 final. This should
be the last fastimport update before then.
--
Documentation/git-fast-import.txt | 40 +++++++++++++++--
fast-import.c | 81 ++++++++++++++++++++++++++++++++++--
t/t9300-fast-import.sh | 83 +++++++++++++++++++++++++++++++++++++
3 files changed, 195 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index bf1ba67..30ee98d 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -302,7 +302,7 @@ change to the project.
data
('from' SP <committish> LF)?
('merge' SP <committish> LF)?
- (filemodify | filedelete | filerename | filedeleteall)*
+ (filemodify | filedelete | filecopy | filerename | filedeleteall)*
LF
....
@@ -325,13 +325,13 @@ commit message use a 0 length data. Commit messages are free-form
and are not interpreted by Git. Currently they must be encoded in
UTF-8, as fast-import does not permit other encodings to be specified.
-Zero or more `filemodify`, `filedelete`, `filerename` and
-`filedeleteall` commands
+Zero or more `filemodify`, `filedelete`, `filecopy`, `filerename`
+and `filedeleteall` commands
may be included to update the contents of the branch prior to
creating the commit. These commands may be supplied in any order.
However it is recommended that a `filedeleteall` command preceed
-all `filemodify` and `filerename` commands in the same commit, as
-`filedeleteall`
+all `filemodify`, `filecopy` and `filerename` commands in the same
+commit, as `filedeleteall`
wipes the branch clean (see below).
`author`
@@ -497,6 +497,27 @@ here `<path>` is the complete path of the file or subdirectory to
be removed from the branch.
See `filemodify` above for a detailed description of `<path>`.
+`filecopy`
+^^^^^^^^^^^^
+Recursively copies an existing file or subdirectory to a different
+location within the branch. The existing file or directory must
+exist. If the destination exists it will be completely replaced
+by the content copied from the source.
+
+....
+ 'C' SP <path> SP <path> LF
+....
+
+here the first `<path>` is the source location and the second
+`<path>` is the destination. See `filemodify` above for a detailed
+description of what `<path>` may look like. To use a source path
+that contains SP the path must be quoted.
+
+A `filecopy` command takes effect immediately. Once the source
+location has been copied to the destination any future commands
+applied to the source location will not impact the destination of
+the copy.
+
`filerename`
^^^^^^^^^^^^
Renames an existing file or subdirectory to a different location
@@ -517,6 +538,15 @@ location has been renamed to the destination any future commands
applied to the source location will create new files there and not
impact the destination of the rename.
+Note that a `filerename` is the same as a `filecopy` followed by a
+`filedelete` of the source location. There is a slight performance
+advantage to using `filerename`, but the advantage is so small
+that it is never worth trying to convert a delete/add pair in
+source material into a rename for fast-import. This `filerename`
+command is provided just to simplify frontends that already have
+rename information and don't want bother with decomposing it into a
+`filecopy` followed by a `filedelete`.
+
`filedeleteall`
^^^^^^^^^^^^^^^
Included in a `commit` command to remove all files (and also all
diff --git a/fast-import.c b/fast-import.c
index a1cb13f..99a19d8 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -26,10 +26,16 @@ Format of STDIN stream:
lf;
commit_msg ::= data;
- file_change ::= file_clr | file_del | file_rnm | file_obm | file_inm;
+ file_change ::= file_clr
+ | file_del
+ | file_rnm
+ | file_cpy
+ | file_obm
+ | file_inm;
file_clr ::= 'deleteall' lf;
file_del ::= 'D' sp path_str lf;
file_rnm ::= 'R' sp path_str sp path_str lf;
+ file_cpy ::= 'C' sp path_str sp path_str lf;
file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf;
file_inm ::= 'M' sp mode sp 'inline' sp path_str lf
data;
@@ -623,6 +629,31 @@ static void release_tree_entry(struct tree_entry *e)
avail_tree_entry = e;
}
+static struct tree_content *dup_tree_content(struct tree_content *s)
+{
+ struct tree_content *d;
+ struct tree_entry *a, *b;
+ unsigned int i;
+
+ if (!s)
+ return NULL;
+ d = new_tree_content(s->entry_count);
+ for (i = 0; i < s->entry_count; i++) {
+ a = s->entries[i];
+ b = new_tree_entry();
+ memcpy(b, a, sizeof(*a));
+ if (a->tree && is_null_sha1(b->versions[1].sha1))
+ b->tree = dup_tree_content(a->tree);
+ else
+ b->tree = NULL;
+ d->entries[i] = b;
+ }
+ d->entry_count = s->entry_count;
+ d->delta_depth = s->delta_depth;
+
+ return d;
+}
+
static void start_packfile(void)
{
static char tmpfile[PATH_MAX];
@@ -1273,6 +1304,43 @@ del_entry:
return 1;
}
+static int tree_content_get(
+ struct tree_entry *root,
+ const char *p,
+ struct tree_entry *leaf)
+{
+ struct tree_content *t = root->tree;
+ const char *slash1;
+ unsigned int i, n;
+ struct tree_entry *e;
+
+ slash1 = strchr(p, '/');
+ if (slash1)
+ n = slash1 - p;
+ else
+ n = strlen(p);
+
+ for (i = 0; i < t->entry_count; i++) {
+ e = t->entries[i];
+ if (e->name->str_len == n && !strncmp(p, e->name->str_dat, n)) {
+ if (!slash1) {
+ memcpy(leaf, e, sizeof(*leaf));
+ if (e->tree && is_null_sha1(e->versions[1].sha1))
+ leaf->tree = dup_tree_content(e->tree);
+ else
+ leaf->tree = NULL;
+ return 1;
+ }
+ if (!S_ISDIR(e->versions[1].mode))
+ return 0;
+ if (!e->tree)
+ load_tree(e);
+ return tree_content_get(e, slash1 + 1, leaf);
+ }
+ }
+ return 0;
+}
+
static int update_branch(struct branch *b)
{
static const char *msg = "fast-import";
@@ -1658,7 +1726,7 @@ static void file_change_d(struct branch *b)
free(p_uq);
}
-static void file_change_r(struct branch *b)
+static void file_change_cr(struct branch *b, int rename)
{
const char *s, *d;
char *s_uq, *d_uq;
@@ -1694,7 +1762,10 @@ static void file_change_r(struct branch *b)
}
memset(&leaf, 0, sizeof(leaf));
- tree_content_remove(&b->branch_tree, s, &leaf);
+ if (rename)
+ tree_content_remove(&b->branch_tree, s, &leaf);
+ else
+ tree_content_get(&b->branch_tree, s, &leaf);
if (!leaf.versions[1].mode)
die("Path %s not in branch", s);
tree_content_set(&b->branch_tree, d,
@@ -1874,7 +1945,9 @@ static void cmd_new_commit(void)
else if (!prefixcmp(command_buf.buf, "D "))
file_change_d(b);
else if (!prefixcmp(command_buf.buf, "R "))
- file_change_r(b);
+ file_change_cr(b, 1);
+ else if (!prefixcmp(command_buf.buf, "C "))
+ file_change_cr(b, 0);
else if (!strcmp("deleteall", command_buf.buf))
file_change_deleteall(b);
else
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index bf3720d..4b920be 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -648,4 +648,87 @@ test_expect_success \
git diff-tree -M -r M3^ M3 >actual &&
compare_diff_raw expect actual'
+###
+### series N
+###
+
+test_tick
+cat >input <<INPUT_END
+commit refs/heads/N1
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+file copy
+COMMIT
+
+from refs/heads/branch^0
+C file2/newf file2/n.e.w.f
+
+INPUT_END
+
+cat >expect <<EOF
+:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f
+EOF
+test_expect_success \
+ 'N: copy file in same subdirectory' \
+ 'git-fast-import <input &&
+ git diff-tree -C --find-copies-harder -r N1^ N1 >actual &&
+ compare_diff_raw expect actual'
+
+cat >input <<INPUT_END
+commit refs/heads/N2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+clean directory copy
+COMMIT
+
+from refs/heads/branch^0
+C file2 file3
+
+commit refs/heads/N2
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+modify directory copy
+COMMIT
+
+M 644 inline file3/file5
+data <<EOF
+$file5_data
+EOF
+
+INPUT_END
+
+cat >expect <<EOF
+:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5
+:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf
+:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf
+EOF
+test_expect_success \
+ 'N: copy then modify subdirectory' \
+ 'git-fast-import <input &&
+ git diff-tree -C --find-copies-harder -r N2^^ N2 >actual &&
+ compare_diff_raw expect actual'
+
+cat >input <<INPUT_END
+commit refs/heads/N3
+committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+data <<COMMIT
+dirty directory copy
+COMMIT
+
+from refs/heads/branch^0
+M 644 inline file2/file5
+data <<EOF
+$file5_data
+EOF
+
+C file2 file3
+D file2/file5
+
+INPUT_END
+
+test_expect_success \
+ 'N: copy dirty subdirectory' \
+ 'git-fast-import <input &&
+ test `git-rev-parse N2^{tree}` = `git-rev-parse N3^{tree}`'
+
test_done
--
1.5.3.rc0.900.ge7568
^ 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