diff --git a/hgext3rd/fbamend/hiddenoverride.py b/hgext3rd/fbamend/hiddenoverride.py --- a/hgext3rd/fbamend/hiddenoverride.py +++ b/hgext3rd/fbamend/hiddenoverride.py @@ -36,18 +36,21 @@ return revs def loadpinnednodes(repo): - """yield pinned nodes that should be visible""" + """yield pinned nodes that are obsoleted and should be visible""" if repo is None or not repo.local(): return # the "pinned nodes" file name is "obsinhibit" for compatibility reason content = repo.svfs.tryread('obsinhibit') or '' - nodemap = repo.unfiltered().changelog.nodemap + unfi = repo.unfiltered() + nodemap = unfi.changelog.nodemap offset = 0 while True: node = content[offset:offset + 20] if not node: break - if node in nodemap: + # remove unnecessary (non-obsoleted) nodes since pinnedrevs should only + # affect obsoleted revs. + if node in nodemap and unfi[node].obsolete(): yield node offset += 20 @@ -99,12 +102,20 @@ f.write(''.join(nodes)) def runcommand(orig, lui, repo, cmd, fullargs, *args): - shouldpinbefore = shouldpinnodes(repo) + # return directly for non-repo command + if not repo: + return orig(lui, repo, cmd, fullargs, *args) + + shouldpinbefore = shouldpinnodes(repo) | set(loadpinnednodes(repo)) result = orig(lui, repo, cmd, fullargs, *args) # after a command completes, make sure working copy parent and all # bookmarks get "pinned". newpin = shouldpinnodes(repo) - shouldpinbefore - newunpin = getattr(repo, '_tounpinnodes', set()) + newunpin = getattr(repo.unfiltered(), '_tounpinnodes', set()) + # filter newpin by obsolte - ex. if newpin is on a non-obsoleted commit, + # ignore it. + unfi = repo.unfiltered() + newpin = set(n for n in newpin if unfi[n].obsolete()) # only do a write if something has changed if newpin or newunpin: savepinnednodes(repo, newpin, newunpin) @@ -112,6 +123,7 @@ def createmarkers(orig, repo, rels, *args, **kwargs): # this is a way to unpin revs - precursors are unpinned + # note: hg debugobsolete does not call this function unfi = repo.unfiltered() tounpin = getattr(unfi, '_tounpinnodes', set()) for r in rels: diff --git a/tests/test-fbamend-hiddenoverride.t b/tests/test-fbamend-hiddenoverride.t --- a/tests/test-fbamend-hiddenoverride.t +++ b/tests/test-fbamend-hiddenoverride.t @@ -56,3 +56,89 @@ |/ @ 0 A +The order matters - putting bookmarks or moving working copy on non-obsoleted +commits do not pin them. Test this using "debugobsolete" which will not call +"createmarkers". + +Obsolete working copy, and move working copy away should make things disappear + + $ rm -rf .hg && hg init && hg debugdrawdag <<'EOS' + > C E + > | | + > B D + > |/ + > A + > EOS + + $ hg up -q E + $ hg debugobsolete `HGPLAIN=1 hg log -r E -T '{node}'` + obsoleted 1 changesets + $ hg tag --local --remove E + $ hg log -G -T '{rev} {desc}\n' + @ 4 E + | + | o 3 C + | | + o | 2 D + | | + | o 1 B + |/ + o 0 A + + $ hg debugobsolete `HGPLAIN=1 hg log -r D -T '{node}'` + obsoleted 1 changesets + $ hg tag --local --remove D + $ hg log -G -T '{rev} {desc}\n' + @ 4 E + | + | o 3 C + | | + x | 2 D + | | + | o 1 B + |/ + o 0 A + + $ hg update -q C + $ hg log -G -T '{rev} {desc}\n' + @ 3 C + | + o 1 B + | + o 0 A + +Having a bookmark on a commit, obsolete the commit, remove the bookmark + + $ rm -rf .hg && hg init && hg debugdrawdag <<'EOS' + > C E + > | | + > B D + > |/ + > A + > EOS + + $ hg bookmark -i book-e -r E + $ hg debugobsolete `HGPLAIN=1 hg log -r D -T '{node}'` + obsoleted 1 changesets + $ hg debugobsolete `HGPLAIN=1 hg log -r E -T '{node}'` + obsoleted 1 changesets + $ rm .hg/localtags + $ hg log -G -T '{rev} {desc} {bookmarks}\n' + x 4 E book-e + | + | o 3 C + | | + x | 2 D + | | + | o 1 B + |/ + o 0 A + + $ hg bookmark -d book-e + $ hg log -G -T '{rev} {desc} {bookmarks}\n' + o 3 C + | + o 1 B + | + o 0 A +