# HG changeset patch # User Siddharth Agarwal <sid0@fb.com> # Date 1419974755 28800 # Tue Dec 30 13:25:55 2014 -0800 # Node ID 89bfb999473234344db1dcf6f8bc2c89e7409517 # Parent 8e17f8a1626961ed5eb225b0cfced8a49f01c931 git_handler: handle symlink <-> regular file transitions properly See comment inline for explanation. Also add tests for this (the bug was masked with rename detection disabled -- it only appeared with rename detection enabled). diff --git a/hggit/git_handler.py b/hggit/git_handler.py --- a/hggit/git_handler.py +++ b/hggit/git_handler.py @@ -1337,6 +1337,18 @@ # gitlink no | delete gitlink # gitlink file | delete gitlink and record file # gitlink gitlink | record gitlink + # + # There's an edge case here -- symlink <-> regular file transitions + # are returned by dulwich as separate deletes and adds, not + # modifications. The order of those results is unspecified and could + # be either way round. Handle both cases: + # delete first, then add -- delete stored in 'old = file' case, then + # overwritten by 'new = file' case. + # add first, then delete -- record stored in 'new = file' case, then + # membership check fails in 'old = file' case so is not overwritten + # there. + # This is not an issue for gitlink <-> {symlink, regular file} + # transitions because they write to separate dictionaries. if newmode == 0160000: # new = gitlink gitlinks[newfile] = newsha @@ -1361,7 +1373,9 @@ files[oldfile] = True, None, None else: # old = file - files[oldfile] = True, None, None + # the membership check is explained in a comment above + if oldfile not in files: + files[oldfile] = True, None, None return files, gitlinks, renames diff --git a/tests/test-file-removal.t b/tests/test-file-removal.t --- a/tests/test-file-removal.t +++ b/tests/test-file-removal.t @@ -223,3 +223,59 @@ Date: Mon Jan 1 00:00:10 2007 +0000 add alpha + +test with rename detection enabled + $ hg --config git.similarity=100 clone gitrepo hgreporenames | grep -v '^updating' + importing git objects into hg + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ cd hgreporenames + $ hg log --graph | grep -v ': master' + @ changeset: 8:0995b8a0a943 + | bookmark: master + | tag: default/master + | tag: tip + | user: test <test@example.org> + | date: Mon Jan 01 00:00:18 2007 +0000 + | summary: remove betalink + | + o changeset: 7:a316d3a96c89 + | user: test <test@example.org> + | date: Mon Jan 01 00:00:17 2007 +0000 + | summary: replace file with symlink + | + o changeset: 6:1804acb71f3e + | user: test <test@example.org> + | date: Mon Jan 01 00:00:16 2007 +0000 + | summary: replace symlink with file + | + o changeset: 5:e19c85becc87 + | user: test <test@example.org> + | date: Mon Jan 01 00:00:15 2007 +0000 + | summary: add symlink to beta + | + o changeset: 4:0d3086c3f8c3 + | user: test <test@example.org> + | date: Mon Jan 01 00:00:14 2007 +0000 + | summary: remove foo/bar + | + o changeset: 3:b2406125ef5c + | user: test <test@example.org> + | date: Mon Jan 01 00:00:13 2007 +0000 + | summary: remove alpha + | + o changeset: 2:8b3b2f4b4158 + | user: test <test@example.org> + | date: Mon Jan 01 00:00:12 2007 +0000 + | summary: add foo + | + o changeset: 1:7fe02317c63d + | user: test <test@example.org> + | date: Mon Jan 01 00:00:11 2007 +0000 + | summary: add beta + | + o changeset: 0:ff7a2f2d8d70 + user: test <test@example.org> + date: Mon Jan 01 00:00:10 2007 +0000 + summary: add alpha +