3

To delete a branch, I know at least these commands:

git branch oldbranch -d
git branch oldbranch -D

The first one deletes the branch if it was fully merged, the second one deletes it in any case.

Now consider a workflow where a branch got rebased into master, not merged. The first command won't remove the branch (it was not merged). The second one will delete the branch, but it will do it in any case (even if rebase wasn't done yet). I wonder if there's a safer way to remove the branch, which can be:

  1. in a worse case "delete if diff between the current branch and master is emtpy"
  2. in a better case (since master can have other new commits) "delete if master contains commits which are ~equal to the commits of this branch since its creation" (sure, there can be problems with the "equal" bit in some cases, but for simpler ones..)

Do you know any such command?

YakovL
  • 7,557
  • 12
  • 62
  • 102

3 Answers3

1

You can use git-log to find out if there are any patches on one branch that don't have equivalents on the other:

git log --no-merges --cherry-pick --left-only oldbranch...master

That's a symmetric difference with three dots. --cherry-pick finds "cherry-pickable" commits, ones which don't have an equivalent on the other branch. The symmetric difference would normally show commits from either branch that don't have equivalents on the other; --left-only tells it to only show commits from the left branch (oldbranch, in this case).

If you don't care to see the commits, you can substitute git rev-list --count for git log.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
1

In case

  1. in a better case (since master can have other new commits) "delete if master contains commits which are ~equal to the commits of this branch since its creation" (sure, there can be problems with the "equal" bit in some cases, but for simpler ones..)
git rebase master oldbranch
git checkout master
git branch -d oldbranch

should do it, rebase identifies and ignores commits you've already cherrypicked, and if that's all of them master and oldbranch will be the same commit, i.e. oldbranch is already merged and the deletion succeeds.

But case

  1. in a worse case "delete if diff between the current branch and master is empty"

is distinguishable, it's possible to have arrived at the same result but with different individual steps, where it's only the cumulative effect that matches. The question here is, what do you want your result history to look like? You have to use different commands to get different results.

So the most trivial sequence I can come up with to hit all your desiderata is

if [[ `git rev-parse master:` = `git rev-parse oldbranch:` ]]; then
        echo '`oldbranch` tip identical to master tip, not bothering with rebase, deleting'
        git checkout master &&
        git branch -D oldbranch
else
        git rebase master oldbranch &&
        git checkout master &&
        git branch -d oldbranch && echo oldbranch completely merged, deleting
fi

and the case not handled here is whether the two branch tips arrived at partially-overlapping cumulative differences and divvied the changes up differently, and for that you just have to decide what historical record will be most useful. I'd just merge.

jthill
  • 55,082
  • 5
  • 77
  • 137
  • ok, this works, but only if `git branch --set-upstrem-to=master` is done before rebasing. That's 4 commands; is it possible to create an alias using git itself? – YakovL Apr 28 '19 at 15:50
  • I'm sorry, I don't understand any of that. I think it might be best to ask a new question about your attempt to implement this, referencing this one and showing exactly what you're looking at and where its behavior differs from what you want and expect, because I don't see how anything could depend on the upstream setting here. – jthill Apr 28 '19 at 17:47
  • Yeap, you are probably right, this may deserve a new question. It's just without setting upstream I got an error similar to this https://stackoverflow.com/q/32056324/3995261, but aliasing a set of commands is indeed a separate issue – YakovL Apr 28 '19 at 20:45
  • that question is about results from a different command, with different arguments, in a different situation. Please post (preferably as a separate question) concrete details including the actual commands you're issuing, showing the actual results you're getting, in a way that others can reproduce the situation. Characterizations are not facts. "an error similar to" is simply the opposite of helpful. – jthill Apr 28 '19 at 20:54
0

Few ways to mark which commit was picked during cherry-pick

cherry-pick -x

You can use cherry-pick -x so you will have the original commit which was picked for the cherry-pick

git notes

Use git notes to add notes (notes are not part of the SHA-1) and can be deleted or modified without affecting the commit ID

Find out if branch contains commits

Once you have the original commits you can use a script to verify that all the commits are in the destination branch with the

git branch --contains <commit>
CodeWizard
  • 128,036
  • 21
  • 144
  • 167