[PATCH 3 of 3 STABLE] merge: while checking unknown files also check link flag (issue5027)
Siddharth Agarwal
sid at less-broken.com
Tue Dec 29 00:59:16 CST 2015
On 12/28/15 22:55, Siddharth Agarwal wrote:
> # HG changeset patch
> # User Siddharth Agarwal <sid0 at fb.com>
> # Date 1451371891 28800
> # Mon Dec 28 22:51:31 2015 -0800
> # Branch stable
> # Node ID b7b6a2945e1ecc40ff3ce93c1cefeae708d4cd29
> # Parent 0562811a731ffdc1d6317d7002e860ba51e8a844
> # Available At http://42.netv6.net/sid0-wip/hg/
> # hg pull http://42.netv6.net/sid0-wip/hg/ -r b7b6a2945e1e
> merge: while checking unknown files also check link flag (issue5027)
Patch 2-3 are a bit of an RFC -- I'm not sure what the right behavior is
here. For a file to symlink or symlink to file transition if the
contents remain the same should we overwrite or abort?
>
> Previously, while checking to see whether files were the same, we wouldn't
> compare whether they were symlinks or not on both ends -- just their contents.
>
> This is a very niche case because files are very unlikely to have the same
> contents as symlinks: symlinks pointing to the empty string are prohibited on
> most platforms, and non-empty text files are likely to have newlines in them.
>
> diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
> --- a/hgext/largefiles/overrides.py
> +++ b/hgext/largefiles/overrides.py
> @@ -426,10 +426,10 @@ def overridedebugstate(orig, ui, repo, *
> # The overridden function filters the unknown files by removing any
> # largefiles. This makes the merge proceed and we can then handle this
> # case further in the overridden calculateupdates function below.
> -def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2):
> +def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2, islink):
> if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
> return False
> - return origfn(repo, wctx, mctx, f, f2)
> + return origfn(repo, wctx, mctx, f, f2, islink)
>
> # The manifest merge handles conflicts on the manifest level. We want
> # to handle changes in largefile-ness of files at this level too.
> diff --git a/mercurial/merge.py b/mercurial/merge.py
> --- a/mercurial/merge.py
> +++ b/mercurial/merge.py
> @@ -401,11 +401,13 @@ class mergestate(object):
> """rerun merge process for file path `dfile`"""
> return self._resolve(False, dfile, wctx, labels=labels)[1]
>
> -def _checkunknownfile(repo, wctx, mctx, f, f2):
> +def _checkunknownfile(repo, wctx, mctx, f, f2, islink):
> + # we only check link rather than both link and exec because the exec flag is
> + # easy to fix
> return (repo.wvfs.isfileorlink(f)
> and repo.wvfs.audit.check(f)
> and repo.dirstate.normalize(f) not in repo.dirstate
> - and mctx[f2].cmp(wctx[f]))
> + and (islink != repo.wvfs.islink(f) or mctx[f2].cmp(wctx[f])))
>
> def _checkunknownfiles(repo, wctx, mctx, force, actions):
> """
> @@ -417,10 +419,13 @@ def _checkunknownfiles(repo, wctx, mctx,
> if not force:
> for f, (m, args, msg) in actions.iteritems():
> if m in ('c', 'dc'):
> - if _checkunknownfile(repo, wctx, mctx, f, f):
> + flags, = args
> + if _checkunknownfile(repo, wctx, mctx, f, f, 'l' in flags):
> aborts.append(f)
> elif m == 'dg':
> - if _checkunknownfile(repo, wctx, mctx, f, args[0]):
> + flags = args[1]
> + if _checkunknownfile(repo, wctx, mctx, f, args[0],
> + 'l' in flags):
> aborts.append(f)
>
> for f in sorted(aborts):
> @@ -434,7 +439,7 @@ def _checkunknownfiles(repo, wctx, mctx,
> actions[f] = ('g', args, msg)
> elif m == 'cm':
> fl2, anc = args
> - different = _checkunknownfile(repo, wctx, mctx, f, f)
> + different = _checkunknownfile(repo, wctx, mctx, f, f, 'l' in fl2)
> if different:
> actions[f] = ('m', (f, f, None, False, anc),
> "remote differs from untracked local")
> diff --git a/tests/test-merge1.t b/tests/test-merge1.t
> --- a/tests/test-merge1.t
> +++ b/tests/test-merge1.t
> @@ -87,11 +87,12 @@ no merges expected
> $ hg add a
> $ hg commit -m "commit #0"
> $ echo This is file b1 > b
> - $ hg add b
> + $ printf this-has-no-newline > no-newline
> + $ hg add b no-newline
> $ hg commit -m "commit #1"
>
> $ hg update 0
> - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
> $ echo This is file c1 > c
> $ hg add c
> $ hg commit -m "commit #2"
> @@ -119,7 +120,36 @@ symlinks shouldn't be followed
> b: untracked file differs
> abort: untracked files in working directory differ from files in requested revision
> [255]
> +don't overwrite symlinks with files with the same contents
> + $ ln -s this-has-no-newline no-newline
> + $ hg merge 1
> + b: untracked file differs
> + no-newline: untracked file differs
> + abort: untracked files in working directory differ from files in requested revision
> + [255]
> +... or vice versa
> + $ hg up --clean 0
> + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> + $ ln -s this-has-no-newline-b no-newline-b
> + $ hg add no-newline-b
> + $ hg commit -m "commit #3"
> + created new head
> + $ hg up --clean 2
> + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
> + $ printf this-has-no-newline-b > no-newline-b
> + $ hg merge 3
> + no-newline-b: untracked file differs
> + abort: untracked files in working directory differ from files in requested revision
> + [255]
> +do overwrite symlinks with identical symlinks
> + $ rm no-newline-b
> + $ ln -s this-has-no-newline-b no-newline-b
> + $ hg merge 3
> + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> + (branch merge, don't forget to commit)
>
> + $ hg up --clean 2
> + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
> $ rm b
> $ echo This is file b2 > b
> #endif
> @@ -128,7 +158,7 @@ merge of b expected
> $ hg merge -f 1
> merging b
> merging for b
> - 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
> + 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
> (branch merge, don't forget to commit)
> $ hg diff --nodates
> diff -r 49035e18a8e6 b
> @@ -136,8 +166,15 @@ merge of b expected
> +++ b/b
> @@ -0,0 +1,1 @@
> +This is file b2
> + diff -r 49035e18a8e6 no-newline
> + --- /dev/null
> + +++ b/no-newline
> + @@ -0,0 +1,1 @@
> + +this-has-no-newline
> + \ No newline at end of file
> $ hg status
> M b
> + M no-newline
> $ cd ..; rm -r t
>
> $ hg init t
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list