view tests/test-copies-unrelated.t @ 42618:c17e6a3e7356

phabricator: handle local:commits time being string or int When setting local:commits arcanist has different behaviour depending on whether the repo is git or hg. With hg it sets the time as a number, since it calls PHP's strtotime on the value, but with git it sets it as a string. Normally this wouldn't be an issue since phabread wouldn't be interacting with Phabricator Revisions for git repos, but Mozilla has a secondary workflow for git users that uses the git-cinnabar tool to interact with their hg repos. When a git-cinnabar user uses the moz-phab tool to submit patches for mozilla-central it makes use of Mozilla's fork of arcanist, which works with their local git version of m-c, and thus sets the local:commit time as a string, and then translates the commit hashes. Currently when encountering such DREVS phabread dies with "TypeError: %d format: a number is required, not str". phabsend also used to set it as a string but wouldn't have encountered the issue with its own DREVs since it would read hg:meta first. Differential Revision: https://phab.mercurial-scm.org/D6650
author Ian Moody <moz-ian@perix.co.uk>
date Tue, 16 Jul 2019 19:18:16 +0100
parents 819712deac69
children 12b8a2ef8d04
line wrap: on
line source

#testcases filelog compatibility changeset

  $ cat >> $HGRCPATH << EOF
  > [extensions]
  > rebase=
  > [alias]
  > l = log -G -T '{rev} {desc}\n{files}\n'
  > EOF

#if compatibility
  $ cat >> $HGRCPATH << EOF
  > [experimental]
  > copies.read-from = compatibility
  > EOF
#endif

#if changeset
  $ cat >> $HGRCPATH << EOF
  > [experimental]
  > copies.read-from = changeset-only
  > copies.write-to = changeset-only
  > EOF
#endif

  $ REPONUM=0
  $ newrepo() {
  >     cd $TESTTMP
  >     REPONUM=`expr $REPONUM + 1`
  >     hg init repo-$REPONUM
  >     cd repo-$REPONUM
  > }

Copy a file, then delete destination, then copy again. This does not create a new filelog entry.
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ hg cp x y
  $ hg ci -qm 'copy x to y'
  $ hg rm y
  $ hg ci -m 'remove y'
  $ hg cp -f x y
  $ hg ci -m 'copy x onto y (again)'
  $ hg l
  @  4 copy x onto y (again)
  |  y
  o  3 remove y
  |  y
  o  2 copy x to y
  |  y
  | o  1 modify x
  |/   x
  o  0 add x
     x
  $ hg debugp1copies -r 4
  x -> y
  $ hg debugpathcopies 0 4
  x -> y
  $ hg graft -r 1
  grafting 1:* "modify x" (glob)
  merging y and x to y
  $ hg co -qC 1
  $ hg graft -r 4
  grafting 4:* "copy x onto y (again)" (glob)
  merging x and y to y

Copy x to y, then remove y, then add back y. With copy metadata in the
changeset, this could easily end up reporting y as copied from x (if we don't
unmark it as a copy when it's removed). Despite x and y not being related, we
want grafts to propagate across the rename.
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ hg mv x y
  $ hg ci -qm 'rename x to y'
  $ hg rm y
  $ hg ci -qm 'remove y'
  $ echo x > y
  $ hg ci -Aqm 'add back y'
  $ hg l
  @  4 add back y
  |  y
  o  3 remove y
  |  y
  o  2 rename x to y
  |  x y
  | o  1 modify x
  |/   x
  o  0 add x
     x
  $ hg debugpathcopies 0 4
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 1
  grafting 1:* "modify x" (glob)
  file 'x' was deleted in local [local] but was modified in other [graft].
  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]

Add x, remove it, then add it back, then rename x to y. Similar to the case
above, but here the break in history is before the rename.
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ hg rm x
  $ hg ci -qm 'remove x'
  $ echo x > x
  $ hg ci -Aqm 'add x again'
  $ hg mv x y
  $ hg ci -m 'rename x to y'
  $ hg l
  @  4 rename x to y
  |  x y
  o  3 add x again
  |  x
  o  2 remove x
  |  x
  | o  1 modify x
  |/   x
  o  0 add x
     x
  $ hg debugpathcopies 0 4
  x -> y
  $ hg graft -r 1
  grafting 1:* "modify x" (glob)
  merging y and x to y
  $ hg co -qC 1
  $ hg graft -r 4
  grafting 4:* "rename x to y" (glob)
  merging x and y to y

Add x, modify it, remove it, then add it back, then rename x to y. Similar to
the case above, but here the re-added file's nodeid is different from before
the break.

  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ echo x3 > x
  $ hg ci -qm 'modify x again'
  $ hg co -q 1
  $ hg rm x
  $ hg ci -qm 'remove x'
# Same content to avoid conflicts
  $ hg revert -r 1 x
  $ hg ci -Aqm 'add x again'
  $ hg mv x y
  $ hg ci -m 'rename x to y'
  $ hg l
  @  5 rename x to y
  |  x y
  o  4 add x again
  |  x
  o  3 remove x
  |  x
  | o  2 modify x again
  |/   x
  o  1 modify x
  |  x
  o  0 add x
     x
  $ hg debugpathcopies 0 5
  x -> y (no-filelog !)
#if no-filelog
  $ hg graft -r 2
  grafting 2:* "modify x again" (glob)
  merging y and x to y
#else
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 2
  grafting 2:* "modify x again" (glob)
  file 'x' was deleted in local [local] but was modified in other [graft].
  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]
#endif
  $ hg co -qC 2
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 5
  grafting 5:* "rename x to y"* (glob)
  file 'x' was deleted in other [graft] but was modified in local [local].
  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]

Add x, remove it, then add it back, rename x to y from the first commit.
Similar to the case above, but here the break in history is parallel to the
rename.
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ hg rm x
  $ hg ci -qm 'remove x'
  $ echo x > x
  $ hg ci -Aqm 'add x again'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ hg mv x y
  $ hg ci -qm 'rename x to y'
  $ hg l
  @  4 rename x to y
  |  x y
  | o  3 modify x
  | |  x
  | o  2 add x again
  | |  x
  | o  1 remove x
  |/   x
  o  0 add x
     x
  $ hg debugpathcopies 2 4
  x -> y
  $ hg graft -r 3
  grafting 3:* "modify x" (glob)
  merging y and x to y
  $ hg co -qC 3
  $ hg graft -r 4
  grafting 4:* "rename x to y" (glob)
  merging x and y to y

Add x, remove it, then add it back, rename x to y from the first commit.
Similar to the case above, but here the re-added file's nodeid is different
from the base.
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ hg rm x
  $ hg ci -qm 'remove x'
  $ echo x2 > x
  $ hg ci -Aqm 'add x again with different content'
  $ hg co -q 0
  $ hg mv x y
  $ hg ci -qm 'rename x to y'
  $ hg l
  @  3 rename x to y
  |  x y
  | o  2 add x again with different content
  | |  x
  | o  1 remove x
  |/   x
  o  0 add x
     x
  $ hg debugpathcopies 2 3
  x -> y
BROKEN: This should merge the changes from x into y
  $ hg graft -r 2
  grafting 2:* "add x again with different content" (glob)
  $ hg co -qC 2
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 3
  grafting 3:* "rename x to y" (glob)
  file 'x' was deleted in other [graft] but was modified in local [local].
  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]

Add x on two branches, then rename x to y on one side. Similar to the case
above, but here the break in history is via the base commit.
  $ newrepo
  $ echo a > a
  $ hg ci -Aqm 'base'
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ echo x > x
  $ hg ci -Aqm 'add x again'
  $ hg mv x y
  $ hg ci -qm 'rename x to y'
  $ hg l
  @  4 rename x to y
  |  x y
  o  3 add x again
  |  x
  | o  2 modify x
  | |  x
  | o  1 add x
  |/   x
  o  0 base
     a
  $ hg debugpathcopies 1 4
  x -> y
  $ hg graft -r 2
  grafting 2:* "modify x" (glob)
  merging y and x to y
  $ hg co -qC 2
  $ hg graft -r 4
  grafting 4:* "rename x to y"* (glob)
  merging x and y to y

Add x on two branches, with same content but different history, then rename x
to y on one side. Similar to the case above, here the file's nodeid is
different between the branches.
  $ newrepo
  $ echo a > a
  $ hg ci -Aqm 'base'
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ echo x2 > x
  $ hg ci -m 'modify x'
  $ hg co -q 0
  $ touch x
  $ hg ci -Aqm 'add empty x'
# Same content to avoid conflicts
  $ hg revert -r 1 x
  $ hg ci -m 'modify x to match commit 1'
  $ hg mv x y
  $ hg ci -qm 'rename x to y'
  $ hg l
  @  5 rename x to y
  |  x y
  o  4 modify x to match commit 1
  |  x
  o  3 add empty x
  |  x
  | o  2 modify x
  | |  x
  | o  1 add x
  |/   x
  o  0 base
     a
  $ hg debugpathcopies 1 5
  x -> y (no-filelog !)
#if filelog
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 2
  grafting 2:* "modify x" (glob)
  file 'x' was deleted in local [local] but was modified in other [graft].
  You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]
#else
  $ hg graft -r 2
  grafting 2:* "modify x" (glob)
  merging y and x to y
#endif
  $ hg co -qC 2
BROKEN: This should succeed and merge the changes from x into y
  $ hg graft -r 5
  grafting 5:* "rename x to y"* (glob)
  file 'x' was deleted in other [graft] but was modified in local [local].
  You can use (c)hanged version, (d)elete, or leave (u)nresolved.
  What do you want to do? u
  abort: unresolved conflicts, can't continue
  (use 'hg resolve' and 'hg graft --continue')
  [255]

Copies via null revision (there shouldn't be any)
  $ newrepo
  $ echo x > x
  $ hg ci -Aqm 'add x'
  $ hg cp x y
  $ hg ci -m 'copy x to y'
  $ hg co -q null
  $ echo x > x
  $ hg ci -Aqm 'add x (again)'
  $ hg l
  @  2 add x (again)
     x
  o  1 copy x to y
  |  y
  o  0 add x
     x
  $ hg debugpathcopies 1 2
  $ hg debugpathcopies 2 1
  $ hg graft -r 1
  grafting 1:* "copy x to y" (glob)