comparison mercurial/cmdutil.py @ 48976:877d7e1a4223 stable

amend: fix amend with copies in extras If copy information is stored only in the commit extras and not in filelogs, then they get lost on amend if the file wasn't also modified in the working copy. That's because we create `filectx` object from the old commit in those cases, and the `.copysource()` of such objects read only from the filelog. This patch fixes it by always creating a new `memfilectx` in these cases, passing the calculated copy information to it. Differential Revision: https://phab.mercurial-scm.org/D12387
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 18 Mar 2022 21:15:54 -0700
parents 9f1b9e128788
children c80544aa4971 770e1352e9f9
comparison
equal deleted inserted replaced
48975:e3c75d65d589 48976:877d7e1a4223
2904 mergeutil.checkunresolved(ms) 2904 mergeutil.checkunresolved(ms)
2905 2905
2906 filestoamend = {f for f in wctx.files() if matcher(f)} 2906 filestoamend = {f for f in wctx.files() if matcher(f)}
2907 2907
2908 changes = len(filestoamend) > 0 2908 changes = len(filestoamend) > 0
2909 if changes: 2909 changeset_copies = (
2910 repo.ui.config(b'experimental', b'copies.read-from')
2911 != b'filelog-only'
2912 )
2913 # If there are changes to amend or if copy information needs to be read
2914 # from the changeset extras, we cannot take the fast path of using
2915 # filectxs from the old commit.
2916 if changes or changeset_copies:
2910 # Recompute copies (avoid recording a -> b -> a) 2917 # Recompute copies (avoid recording a -> b -> a)
2911 copied = copies.pathcopies(base, wctx, matcher) 2918 copied = copies.pathcopies(base, wctx, matcher)
2912 if old.p2: 2919 if old.p2:
2913 copied.update(copies.pathcopies(old.p2(), wctx, matcher)) 2920 copied.update(copies.pathcopies(old.p2(), wctx, matcher))
2914 2921
2925 if (f not in filestoamend or not samefile(f, wctx, base)) 2932 if (f not in filestoamend or not samefile(f, wctx, base))
2926 ] 2933 ]
2927 2934
2928 def filectxfn(repo, ctx_, path): 2935 def filectxfn(repo, ctx_, path):
2929 try: 2936 try:
2937 # Return None for removed files.
2938 if path in wctx.removed():
2939 return None
2940
2930 # If the file being considered is not amongst the files 2941 # If the file being considered is not amongst the files
2931 # to be amended, we should return the file context from the 2942 # to be amended, we should use the file context from the
2932 # old changeset. This avoids issues when only some files in 2943 # old changeset. This avoids issues when only some files in
2933 # the working copy are being amended but there are also 2944 # the working copy are being amended but there are also
2934 # changes to other files from the old changeset. 2945 # changes to other files from the old changeset.
2935 if path not in filestoamend: 2946 if path in filestoamend:
2936 return old.filectx(path) 2947 fctx = wctx[path]
2937 2948 else:
2938 # Return None for removed files. 2949 fctx = old.filectx(path)
2939 if path in wctx.removed():
2940 return None
2941
2942 fctx = wctx[path]
2943 flags = fctx.flags() 2950 flags = fctx.flags()
2944 mctx = context.memfilectx( 2951 mctx = context.memfilectx(
2945 repo, 2952 repo,
2946 ctx_, 2953 ctx_,
2947 fctx.path(), 2954 fctx.path(),