2013-07-01 23:04:53 +04:00
|
|
|
bail if the user does not have dulwich
|
|
|
|
$ python -c 'import dulwich, dulwich.repo' || exit 80
|
|
|
|
|
|
|
|
$ echo "[extensions]" >> $HGRCPATH
|
2018-01-09 17:08:01 +03:00
|
|
|
$ echo "hggit=$TESTDIR/../hgext/hggit" >> $HGRCPATH
|
2013-07-01 23:04:53 +04:00
|
|
|
$ echo 'hgext.graphlog =' >> $HGRCPATH
|
|
|
|
$ echo "[git]" >> $HGRCPATH
|
|
|
|
$ echo "branch_bookmark_suffix=_bookmark" >> $HGRCPATH
|
|
|
|
|
|
|
|
$ GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
|
|
|
|
$ GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
|
|
|
|
$ GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
|
|
|
|
$ GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
|
|
|
|
$ GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
|
|
|
|
$ GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
|
|
|
|
|
|
|
|
$ count=10
|
|
|
|
$ commit()
|
|
|
|
> {
|
|
|
|
> GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
|
|
|
|
> GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
|
|
|
|
> git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
|
|
|
|
> count=`expr $count + 1`
|
|
|
|
> }
|
|
|
|
$ hgcommit()
|
|
|
|
> {
|
|
|
|
> HGDATE="2007-01-01 00:00:$count +0000"
|
|
|
|
> hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
|
|
|
|
> count=`expr $count + 1`
|
|
|
|
> }
|
|
|
|
|
|
|
|
$ git config --global push.default matching
|
|
|
|
$ git init --bare gitrepo1
|
|
|
|
Initialized empty Git repository in $TESTTMP/gitrepo1/
|
|
|
|
|
|
|
|
$ hg init hgrepo
|
|
|
|
$ cd hgrepo
|
|
|
|
$ hg branch -q branch1
|
|
|
|
$ hg bookmark branch1_bookmark
|
|
|
|
$ echo f1 > f1
|
|
|
|
$ hg add f1
|
|
|
|
$ hgcommit -m "add f1"
|
|
|
|
$ hg branch -q branch2
|
|
|
|
$ hg bookmark branch2_bookmark
|
|
|
|
$ echo f2 > f2
|
|
|
|
$ hg add f2
|
|
|
|
$ hgcommit -m "add f2"
|
|
|
|
$ hg log --graph
|
|
|
|
@ changeset: 1:600de9b6d498
|
|
|
|
| branch: branch2
|
|
|
|
| bookmark: branch2_bookmark
|
|
|
|
| tag: tip
|
|
|
|
| user: test
|
|
|
|
| date: Mon Jan 01 00:00:11 2007 +0000
|
|
|
|
| summary: add f2
|
|
|
|
|
|
|
|
|
o changeset: 0:40a840c1f8ae
|
|
|
|
branch: branch1
|
|
|
|
bookmark: branch1_bookmark
|
|
|
|
user: test
|
|
|
|
date: Mon Jan 01 00:00:10 2007 +0000
|
|
|
|
summary: add f1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$ hg push ../gitrepo1
|
|
|
|
pushing to ../gitrepo1
|
|
|
|
searching for changes
|
|
|
|
adding objects
|
|
|
|
added 2 commits with 2 trees and 2 blobs
|
|
|
|
|
|
|
|
$ cd ..
|
|
|
|
|
|
|
|
$ cd gitrepo1
|
|
|
|
$ git symbolic-ref HEAD refs/heads/branch1
|
|
|
|
$ git branch
|
|
|
|
* branch1
|
|
|
|
branch2
|
|
|
|
$ cd ..
|
|
|
|
|
|
|
|
$ git clone gitrepo1 gitrepo2
|
|
|
|
Cloning into 'gitrepo2'...
|
|
|
|
done.
|
|
|
|
$ cd gitrepo2
|
2018-01-09 16:53:20 +03:00
|
|
|
$ git checkout branch1
|
2013-07-01 23:04:53 +04:00
|
|
|
Already on 'branch1'
|
2017-11-24 23:04:54 +03:00
|
|
|
Your branch is up to date with 'origin/branch1'. (?)
|
2018-06-11 20:26:31 +03:00
|
|
|
Your branch is up to date with 'origin/branch1'. (?)
|
2018-06-12 17:20:22 +03:00
|
|
|
Your branch is up-to-date with 'origin/branch1'. (?)
|
|
|
|
Your branch is up-to-date with 'origin/branch1'. (?)
|
2013-07-01 23:04:53 +04:00
|
|
|
$ echo g1 >> f1
|
|
|
|
$ git add f1
|
|
|
|
$ commit -m "append f1"
|
|
|
|
$ git checkout branch2
|
|
|
|
Switched to a new branch 'branch2'
|
2017-11-24 23:04:54 +03:00
|
|
|
Branch '?branch2'? set up to track remote branch '?branch2'? from '?origin'?. (re)
|
2013-07-01 23:04:53 +04:00
|
|
|
$ echo g2 >> f2
|
|
|
|
$ git add f2
|
|
|
|
$ commit -m "append f2"
|
|
|
|
$ git push origin
|
|
|
|
To $TESTTMP/gitrepo1
|
git_handler: don't store rename source if branch info is stored
Consider a Mercurial commit with hash 'h1'. Originally, if the only Mercurial
field stored is the branch info (which is stored in the commit message rather
than as an extra field), we'd store the rename source explicitly as a Git extra
field -- let's call the original exported hash 'g1'.
In Git, some operations throw all extra fields away. (One such example is a
rebase.) If such an operation happens, we'll be left with a frankencommit with
the branch info but without the rename source. Let's call this hash 'g2'. For a
setup where Git is the source of truth, let's say that this 'g2' frankencommit
is what gets pushed to the server.
When 'g2' is subsequently imported into Mercurial, we'd look at the fact that
it contains a Mercurial field in the commit message and believe that it was a
legacy commit from the olden days when all info was stored in the commit
message. In that case, in an attempt to preserve the hash, we wouldn't store
any extra rename source info, resulting in 'h1'. Then, when the commit is
re-exported to Git, we'd add the rename source again and produce 'g1' -- and
thus break bidirectionality.
Prevent this situation by not storing the rename source if we're adding branch
info to the commit message. Then for 'h1' we export as 'g2' directly and never
produce 'g1'.
What happens if we not only need to store branch info but also other extra
info, like renames? For 'h1' we'd produce 'g1', then it'd be rewritten on the
Git side to 'g2' throwing away all that extra information. 'g2' being
subsequently imported into Mercurial would produce a new hash, say 'h2'. That's
fine because the commit did get rewritten in Git. We unfortunately wouldn't
perform rename detection thinking that the commit is from Mercurial and had no
renames recorded there, but when the commit is re-exported to Git we'd export
it to 'g2' again. This at least preserves bidirectionality.
2015-02-27 09:14:44 +03:00
|
|
|
bbfe79a..d8aef79 branch1 -> branch1
|
|
|
|
288e92b..f8f8de5 branch2 -> branch2
|
|
|
|
make sure the commit doesn't have an HG:rename-source annotation
|
|
|
|
$ git cat-file commit d8aef79
|
|
|
|
tree b5644d8071b8a5963b8d1fd089fb3fdfb14b1203
|
|
|
|
parent bbfe79acf62dcd6a97763e2a67424a6de8a96941
|
|
|
|
author test <test@example.org> 1167609612 +0000
|
|
|
|
committer test <test@example.org> 1167609612 +0000
|
|
|
|
|
|
|
|
append f1
|
2013-07-01 23:04:53 +04:00
|
|
|
$ cd ..
|
|
|
|
|
|
|
|
$ cd hgrepo
|
|
|
|
$ hg pull ../gitrepo1
|
|
|
|
pulling from ../gitrepo1
|
|
|
|
importing git objects into hg
|
|
|
|
(run 'hg heads' to see heads)
|
|
|
|
$ hg log --graph
|
2014-12-03 01:17:09 +03:00
|
|
|
o changeset: 3:ae8eb55f7090
|
2013-07-01 23:04:53 +04:00
|
|
|
| bookmark: branch2_bookmark
|
|
|
|
| tag: default/branch2
|
|
|
|
| tag: tip
|
|
|
|
| parent: 1:600de9b6d498
|
|
|
|
| user: test <test@example.org>
|
|
|
|
| date: Mon Jan 01 00:00:13 2007 +0000
|
|
|
|
| summary: append f2
|
|
|
|
|
|
2014-12-03 01:17:09 +03:00
|
|
|
| o changeset: 2:8211cade99e4
|
2013-07-01 23:04:53 +04:00
|
|
|
| | bookmark: branch1_bookmark
|
|
|
|
| | tag: default/branch1
|
|
|
|
| | parent: 0:40a840c1f8ae
|
|
|
|
| | user: test <test@example.org>
|
|
|
|
| | date: Mon Jan 01 00:00:12 2007 +0000
|
|
|
|
| | summary: append f1
|
|
|
|
| |
|
|
|
|
@ | changeset: 1:600de9b6d498
|
|
|
|
|/ branch: branch2
|
|
|
|
| user: test
|
|
|
|
| date: Mon Jan 01 00:00:11 2007 +0000
|
|
|
|
| summary: add f2
|
|
|
|
|
|
|
|
|
o changeset: 0:40a840c1f8ae
|
|
|
|
branch: branch1
|
|
|
|
user: test
|
|
|
|
date: Mon Jan 01 00:00:10 2007 +0000
|
|
|
|
summary: add f1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$ cd ..
|