Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: Discard all changes on remote branch and push local changes without force push

The case is similar to : Git: Discard all changes on a diverged local branch.

Differences:

  • I want to discard changes which have been pushed to remote repository,
  • git push origin foo:foo --force is rejected (origin doesn't allow force pushing).

Given commit graph:

A--B--C--O1--O2--O3 (foo)
       \
         L1--L2--L3 (origin/foo)

I want to achieve this if possible:

A--B--C--O1--O2--O3 (foo origin/foo)

If above is impossible then following is ok for me:

A--B--C--O1--O2--O3--M1 (foo)
       \            /
         L1--L2--L3 (origin/foo)

but I want git diff M1..03 be empty i.e. discard all changes introduced in origin/foo. And -s ours strategy doesn't help because this only works for conflicts and non-conflicting changes will still be added to M1.

How can I do this?

SOLUTION (by Mohan Kumar P)

Delete remote branch and push. git should create remote branch automatically if it's tracked (check git branch -vv).

To achieve this:

A--B--C--O1--O2--O3 (foo origin/foo)
       \
         L1--L2--L3

type:

git push origin --delete foo
git checkout foo  # Git ≥ 1.6.6.
git push origin foo
like image 263
WloHu Avatar asked Sep 30 '16 06:09

WloHu


1 Answers

The -s ours strategy does work. It's the -X ours "strategy argument" that does not work (for the reason you give).

I think calling these both ours, and then furthermore calling one a "strategy" and the other a "strategy argument" was at best poor planning, as it's confusing, to say the least. (It arose because the -X values are arguments that are passed on to the driver selected by the -s argument—but this explanation just makes it even worse: "The -s argument is the strategy and the -X arguments are the arguments to the strategy from the first argument." "What, so they're argument arguments!? ... Wait, what are we arguing about again?")

Nonetheless, the -s ours strategy really does precisely what you're asking for: it pretends to merge, without even looking at the other branch. Hence, if you are on branch foo whose upstream is origin/foo and you have the graph you have drawn as the starting position, then:

git merge -s ours origin/foo

(perhaps with an explicit -m message as well, or you can use the editor when it runs to explain the merge) will give you the final graph you drew.

like image 144
torek Avatar answered Sep 23 '22 23:09

torek