Disclaimer: Opinions expressed on this blog are solely my own and do not express the views or opinions of my employer(s), past or present.
Updated: 17 July 2015
NOTE: There may be some (ok perhaps a lot of) mistakes with regards to Phabricator and Arcanist terminology because of my lack of familiarity with these tools. But I think you should be able to get the gist of this post despite my mistakes.
Backstory / Scenario
Suppose you are using Phabricator and like a true command line addict, you make use of Arcanist and create a feature branch using
arc feature. Being the git power user that you are, you go on to perform many
git resets (various flavors),
git rebases (various flavors again),
git branch -D’s, etc as you are making changes to your code. Along with several
arc diffs as you update your Revision on Phabricator. One thing led to another and suddenly you realize… you deleted the branch you created using
arc feature, or messed it up to the point of no recognition. And you want to get it back to exactly the same state as the Revision on Phabricator, but you don’t know how.
That was exactly the scenario that happened to me. Reading the Phabricator docs and googling around for answers didn’t help much. Eventually I tried something which has worked for me. I hope it works for you, too.
Step 0: Assumptions
- The Revision that you’ve sent for review using
arc diffis available on your Phabricator server.
- You have the actual git branch for the Revision created by
arc diffsomewhere, whether it’s a local or remote git repository. If you’ve configured Phabricator to do a force push onto a branch on a remote Git repo each time you do an
arc diff, then you can probably find the branch on the remote.
Carry on if both assumptions above are true for you. Otherwise, you may stop reading.
Some terminology I wish to introduce at this point:
- The branch that we want to restore is
awesome-feature-X. That is, you originally created it using an
arc feature awesome-feature-Xcommand.
- The corresponding Phabricator Revision for
arc feature awesome-feature-Xis
origingit remote, there is a branch called
FBR_D1882_awesome-feature-Xthat corresponds to the Phabricator Revision
We will also assume that
D1882contains the follow commits, from oldest to most recent, in chronological order:
fec32ab8 Add README.md
25ad51ee Create AwesomeController
39cf115d Enable CORS for AwesomeController
and the parent of commit
fec32ab8 is commit
da1522c3. Do note that
da1522c3 is not part of Revision
Step 1: Delete the branch with the same name as the feature branch
That is assuming you have, in your effort to restore the feature branch, actually created a branch of the same name. If you have indeed done so and on that branch, you have changes that you want to play on top of the a restored feature branch, please rename the branch to something else before you carry on.
Delete the branch using:
git branch -D awesome-feature-X
Step 2: Create a new branch whose HEAD is the same as the parent of the oldest commit in the feature branch you want to restore
In Step 0, we assumed that Phabricator Revision,
D1882, contains the following commits, from least recent to most recent, in chronological order:
fec32ab8 Add README.md 25ad51ee Create AwesomeController 39cf115d Enable CORS for AwesomeController
The commit we’re interested in is the parent of
fec32ab8, which we earlier assumed is
We need a temporary branch whose
da1522c3. Let’s call this temporary branch
temp-helper-branch and create it:
git checkout -b temp-helper-branch da1522c3
Step 3: Use
arc feature to create a branch with the same name as the feature branch
At the end of the last step,
temp-helper-branch should be the currently active branch and its
HEAD should be commit
da1522c3. Now you gotta use
arc feature to create a feature branch with the same name as the one you want to restore:
arc feature awesome-feature-X
Step 4: Fetch from the
At Step 0, we assumed that at the
origin remote, there is a branch named
FBR_D1882_awesome-feature-X that’s created by Phbricator for
D1882. Let’s fetch all the updates from
origin, which will also update the remote tracking branch
origin/FBR_D1882_awesome-feature-X on your local git repository (or create it if it does not exist):
git fetch origin
Step 5: Fast forward merge
origin/FBR_D1882_awesome-feature-X branch on top of
You should still be at branch
awesome-feature-X. Now execute:
git merge --ff-only origin/FBR_D1882_awesome-feature-X
Tadah! You got your feature branch back. Now you can apply any changes you want on top of this and run
arc diff as if your feature branch was never accidentally deleted in the first place.
Step 6: Delete the unnecessary branch we’ve created along the way
git branch -D temp-helper-branch