Mercurial > hg
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(), |