Yan Han's blog

On Computer Technology

06 Jul 2015

How to restore a deleted `arc feature` branch

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 merges, 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

  1. The Revision that you’ve sent for review using arc diff is available on your Phabricator server.
  2. You have the actual git branch for the Revision created by arc diff somewhere, 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:

  1. The branch that we want to restore is awesome-feature-X. That is, you originally created it using an arc feature awesome-feature-X command.

  2. The corresponding Phabricator Revision for arc feature awesome-feature-X is D1882.

  3. At the origin git remote, there is a branch called FBR_D1882_awesome-feature-X that corresponds to the Phabricator Revision D1882.

  4. We will also assume that D1882 contains 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 D1882.

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 da1522c3.

We need a temporary branch whose HEAD is 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 origin remote

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 awesome-feature-X

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

Namely, temp-helper-branch:

git branch -D temp-helper-branch

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.

comments powered by Disqus