48

I often rebase feature branches and then want to force push them to the server.

git push --force origin feature-mongodb-support

Is there any shortcut for git push --force origin <current branch>?

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
iblue
  • 29,609
  • 19
  • 89
  • 128
  • 1
    I always set up the config/tracking such that `git push` alone pushes to the default remote tracking branch. If you can do that, you could get down to `git push -f`? (just curious: what's your backup plan in this workflow if you push a bad rebase? I assume you're the only one working on these feature branches?) – mpontillo Jul 12 '12 at 14:22
  • Isn't this question specifically about how to get rid of the current branch name in the often used `git push -f origin ` construct? Then the accepted answer completely misses the point and @Mike's comment should be the accepted answer. – AndreKR Jan 24 '15 at 03:57
  • 1
    I think the best answer is to set it as default: `git config --global push.default current` (from [here](http://stackoverflow.com/a/948397/450913)). – orad Oct 07 '15 at 16:34

8 Answers8

33

You can use aliases to shorten the command. Use it like this:

git config --global alias.fpush "push --force origin"

Now to push your branch just type:

git fpush feature-mongodb-support

Or you can even hardcode the branch name into the command:

git alias fpush "push --force origin feature-mongodb-support"

and use only git fpush to push your precious work into the upstream.

However, non-fast-forward updates are dangerous since you will basically overwrite all the history on server that occurred between the last merge/rebase into your local branch and the forced push. If you need to do them often there is definitely something wrong in your workflow.

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
  • I am the only one working on a feature branch. I just want to keep the feature branche fast-forwardable against the master branch to make my life easier. Is there anything wrong with that? – iblue Jul 12 '12 at 15:10
  • 2
    Yep, it is risky. You will overwrite your branch with just one command. A better point will be to interactively rebase your feature-branch on top of the master branch once the feature is done. You will still have a clean history in your master and there will be no risk regarding all these overwrites. – Sergey K. Jul 12 '12 at 16:15
  • I do this, because I need to incorporate new changes from the master branch to test if the new feature still works with the new master code. Where's the risk? – iblue Jul 12 '12 at 16:20
  • The risk is on overwriting remote branch (together with its history) with some buggy code and loosing your previous work. If this is of no concern to you - just use the solution from the answer. – Sergey K. Jul 12 '12 at 16:24
  • Oh, sure. But if I just do a `git rebase master` in the feature branch, then nothing bad can happen. Am I right? – iblue Jul 12 '12 at 16:29
  • It can. Depends on the actual changes in master. So it is up to you to decide whether the risk is acceptable :) – Sergey K. Jul 12 '12 at 16:35
  • The `git rebase master` at least allows you to back out if the rebase doesn't happen cleanly (via `git rebase --abort`) – Kzqai Jun 03 '13 at 22:24
  • 1
    If you follow this advice and include the remote name (typically `origin`) in your git alias, you may have problems with bash `[tab]` completion still trying to add the remote instead of skipping straight to offering branch names. To fix this, define your own custom replacement function in `~/.profile` after sourcing bash_completion: `_git_fpush() { _git_branch; }` (where "fpush" matches the name of your git alias.) This will cause bash to treat your alias the same as the `branch` command. – beporter Oct 23 '15 at 14:52
  • You say frequent force pushes are wrong. There are 2 ways to update long-living branches: merge and rebase. When you choose the rebase method, you need to force push. How else would you do that, if the requirement is to have a clean, straight history on the branch? – Ben Bucksch Nov 05 '21 at 23:10
  • @BenBucksch imagine you have 10 developers working on this branch and between your rebase and forced push someone else has pushed his payload to that branch. The result will be you just overwrite their work with your forced push. Keeping history streamlined this way is ok for long-lasting private branches, and here by private I mean situations when there's only a few developers on that branch. For branches where tens of developers are collaborating, forced pushes will wreck havoc. – Sergey K. Nov 06 '21 at 23:54
  • Agreed, force push works only when there's a single developer. (Or manual coordination, which is to be avoided.) – Ben Bucksch Nov 08 '21 at 00:37
9

After reading these answers and reading this answer to a related question (https://stackoverflow.com/a/18782415/586), I created this alias to force push to origin based on the current branch name:

fp = "!git push -f origin \"$(git rev-parse --abbrev-ref HEAD)\""
Community
  • 1
  • 1
jlleblanc
  • 3,510
  • 25
  • 26
  • How would this work if the remote branch (that we push to) does not have the same name as the local branch? – user1021726 Mar 05 '15 at 09:43
  • @user1021726 it doesn't. – jlleblanc Mar 05 '15 at 17:16
  • This is the answer that cover the whole question... with the limitation that the local branch and remote branch need to have the same name. – Damien Sep 18 '17 at 14:20
  • @jlleblanc is there any way for me to exclude master? i.e. "force push current branch to origin ONLY IF the current branch is something other than master" -- reason for this is because sometimes I accidentally do "git fp" on master and if there are no branch protection rules in place on the repo, that would be bad – James Wierzba Apr 24 '23 at 19:08
9

You can change the default behaviour by setting the push.default property :

git config --global push.default current

then:

git push -f

will force a push to you current branch.

Here is a copy/paste from http://schacon.github.io/git/git-config.html:

push.default

Defines the action git push should take if no refspec is given on the command line, no refspec is configured in the remote, and no refspec is implied by any of the options given on the command line. Possible values are:

  • nothing - do not push anything.

  • matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default.

  • upstream - push the current branch to its upstream branch.

  • tracking - deprecated synonym for upstream.

  • current - push the current branch to a branch of the same name.

Clijsters
  • 4,031
  • 1
  • 27
  • 37
Irgoff
  • 101
  • 1
  • 4
3

If you use oh my zsh you can simply do

ggfl

which will do this for you

git push --force-with-lease origin <your_argument>/$(current_branch)

https://github.com/robbyrussell/oh-my-zsh/wiki/Cheatsheet

Lukas
  • 9,752
  • 15
  • 76
  • 120
1

This should do the trick:

git alias fpush "push --force origin"

Which will let you use git fpush as a shorter alternative.

Wes Hardaker
  • 21,735
  • 2
  • 38
  • 69
  • Unless I'm mistaken, this pushes *all* branches which happen to have local changes, including potentially master, or completely unrelated branches, not just the current branch. Combined with the force push, this is extremely dangerous. – Ben Bucksch Nov 05 '21 at 23:17
0

To automatically force-push to the branch that is tracked (regardless of its name and upstream), I've devised this alias:

fbrpush=!git push $(git rev-parse --abbrev-ref=loose --symbolic-full-name @{upstream} \
                    | sed 's:/: +:')

(line is broken for readability)

(based on another SO answer)

Nikolaj Š.
  • 1,457
  • 1
  • 10
  • 17
0

The current branch name can also be inferred automatically.

I use a small shell script to do the force push to the current branch:

git branch | grep '*' | awk '{print $2}' | xargs -I % git push origin % -f

The command git branch tags the current branch with * symbol, so we can get the relevant line with grep '*' and parse it to get the branch name.

Then the shortcut command can be defined as an alias in .bashrc or .zshrc:

alias gfp=/path/to/script

Update.

Since Git 2.22 (see this answer: stackoverflow.com/a/6245587/1326411 ) it can be simplified to:

alias git-fp='git branch --show-current | xargs -I % git push origin % --force-with-lease'
Vladimir Vagaytsev
  • 2,871
  • 9
  • 33
  • 36
0

to expand on @jlleblanc 's good answer, if you want to add a protection to prevent force pushing to master (this can be really hard to undo)

[alias]
    fp = "!branch=$(git branch --show-current); [[ -z $branch || $branch = 'master' ]] && echo 'Command cannot be used on master branch or when not on branch.' || git push -f origin \"$(git rev-parse --abbrev-ref HEAD)\""

it will do the same thing, except if current branch is master it will skip and print warning

James Wierzba
  • 16,176
  • 14
  • 79
  • 120