Skip to content

Commit

Permalink
fast-import: Support reusing 'from' and brown paper bag fix reset.
Browse files Browse the repository at this point in the history
It was suggested on the mailing list that being able to use `from`
in any commit to reset the current branch is useful in some types of
importers, such as a darcs importer.

We originally did not permit resetting an existing branch with a
new `from` command during a `commit` command, but this restriction
was only to help debug the hacked up cvs2svn that Jon Smirl was
developing in parallel with git-fast-import.  It is probably more
of a problem to disallow it than to allow it.  So now we permit a
`from` during any `commit`.

While making the changes required to permit multiple `from`
commands on the same branch, I discovered we no longer needed the
last_commit field to be set to 0 during a reset, so that was removed.
(Reset was originally setting the field to 0 to signal cmd_from()
that it was OK to execute on the branch.)

While poking around in this section of fast-import I also realized
the `reset` command was not working as intended if the corresponding
`from` command was omitted (as allowed by the BNF grammar and the
code).  If `from` was omitted we cleared out the tree but we left
the tree SHA-1 and parent commit SHA-1 intact.  This is not what
the user intended in this case.  Instead they would be trying to
reset the branch to have no parent and to have no tree, making the
branch look new-born during the next commit.  We now clear these
SHA-1 values during `reset`, ensuring the branch looks new-born if
`from` does not get supplied.

New test cases for these were also added.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
  • Loading branch information
Shawn O. Pearce committed Feb 12, 2007
1 parent b4d2b04 commit ea5e370
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 14 deletions.
21 changes: 10 additions & 11 deletions Documentation/git-fast-import.txt
Original file line number Diff line number Diff line change
Expand Up @@ -349,17 +349,16 @@ their syntax.

`from`
^^^^^^
Only valid for the first commit made on this branch by this
fast-import process. The `from` command is used to specify the commit
to initialize this branch from. This revision will be the first
ancestor of the new commit.

Omitting the `from` command in the first commit of a new branch will
cause fast-import to create that commit with no ancestor. This tends to be
desired only for the initial commit of a project. Omitting the
`from` command on existing branches is required, as the current
commit on that branch is automatically assumed to be the first
ancestor of the new commit.
The `from` command is used to specify the commit to initialize
this branch from. This revision will be the first ancestor of the
new commit.

Omitting the `from` command in the first commit of a new branch
will cause fast-import to create that commit with no ancestor. This
tends to be desired only for the initial commit of a project.
Omitting the `from` command on existing branches is usually desired,
as the current commit on that branch is automatically assumed to
be the first ancestor of the new commit.

As `LF` is not valid in a Git refname or SHA-1 expression, no
quoting or escaping syntax is supported within `<committish>`.
Expand Down
10 changes: 7 additions & 3 deletions fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -1667,8 +1667,10 @@ static void cmd_from(struct branch *b)
if (strncmp("from ", command_buf.buf, 5))
return;

if (b->last_commit)
die("Can't reinitailize branch %s", b->name);
if (b->branch_tree.tree) {
release_tree_content_recursive(b->branch_tree.tree);
b->branch_tree.tree = NULL;
}

from = strchr(command_buf.buf, ' ') + 1;
s = lookup_branch(from);
Expand Down Expand Up @@ -1936,7 +1938,9 @@ static void cmd_reset_branch(void)
sp = strchr(command_buf.buf, ' ') + 1;
b = lookup_branch(sp);
if (b) {
b->last_commit = 0;
hashclr(b->sha1);
hashclr(b->branch_tree.versions[0].sha1);
hashclr(b->branch_tree.versions[1].sha1);
if (b->branch_tree.tree) {
release_tree_content_recursive(b->branch_tree.tree);
b->branch_tree.tree = NULL;
Expand Down
60 changes: 60 additions & 0 deletions t/t9300-fast-import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,64 @@ test_expect_success \
'sed -e s/pack-.*pack/pack-.pack/ edges.list >actual &&
diff -u expect actual'

###
### series J
###

cat >input <<INPUT_END
commit refs/heads/J
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
create J
COMMIT
from refs/heads/branch
reset refs/heads/J
commit refs/heads/J
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
initialize J
COMMIT
INPUT_END
test_expect_success \
'J: reset existing branch creates empty commit' \
'git-fast-import <input'
test_expect_success \
'J: branch has 1 commit, empty tree' \
'test 1 = `git-rev-list J | wc -l` &&
test 0 = `git ls-tree J | wc -l`'

###
### series K
###

cat >input <<INPUT_END
commit refs/heads/K
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
create K
COMMIT
from refs/heads/branch
commit refs/heads/K
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
data <<COMMIT
redo K
COMMIT
from refs/heads/branch^1
INPUT_END
test_expect_success \
'K: reinit branch with from' \
'git-fast-import <input'
test_expect_success \
'K: verify K^1 = branch^1' \
'test `git-rev-parse --verify branch^1` \
= `git-rev-parse --verify K^1`'

test_done

0 comments on commit ea5e370

Please sign in to comment.