22

Every time I want to push my commits (git commit -m "message", git push origin <branch>), I do a pull (git pull origin <branch>).
Is there any way to make git do a pull before performing my push? (on the same branch)

1615903
  • 32,635
  • 12
  • 70
  • 99
Ali Farhoudi
  • 5,350
  • 7
  • 26
  • 44

4 Answers4

27

The Git way to do this is with customize Git hooks.

In your case, you will need to go to the .git/hooks directory on your repository, and add a file named pre-push, which is a script of your choice, e.g. (bash in this example)

#!/bin/bash

echo "pulling ..."
git pull

This script will be called when you do git push and before the actual push.

Obviously, this is just a very naive sample, but I hope you get the idea. There are samples in this directory already. Comment if anything still unclear.

creativeChips
  • 1,177
  • 9
  • 12
  • Why exactly is that a "very naive sample", i.e. what *else* should this hook script do besides what's in your answer? – Kenny Evitt Feb 18 '20 at 18:26
  • this is pretty old answer, but I think I meant case specific logic may be added - conditions, flags, etc. the example is straightforward and in real world will probably be more complex (but it doesn't have to) – creativeChips Feb 20 '20 at 04:29
  • this will never gonna work for new branches before they are in remote – DAG Jul 05 '22 at 15:36
  • @DAG This is not the situation that Ali Farhoudi mentions when his changes are automatically merged with commits from teammates – jokumer Nov 09 '22 at 09:48
11

Based on the OP's comments, they appear to be trying to avoid a merge commit between their recent commits and the commits on the remote, which is normally generated by a git pull when the local and remote histories have diverged.

The explicit way to do this is to first fetch and the rebase, and finally push.

git fetch
git rebase origin/master
git push

A second way to do this is to pass --rebase when invoking git pull.

git pull --rebase

Finally, one can make this the default behavior of git pull by setting the configuration.

git config --global pull.rebase true
merlin2011
  • 71,677
  • 44
  • 195
  • 329
6

You actually don't need to pull before pushing: if there are commits on the remote side you don't have locally, the git push will fail with the message message:

Pushing to git@yourserver:<user>/<repo>.git
To git@yourserver:<user>/<repo>.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/BigMeanCat/CMDA'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.

hint: See the 'Note about fast-forwards' in 'git push --help' for details.

If you have control over the remote server, you can set there:

git config --system receive.denyNonFastForwards true

More generally, you can easily define an alias combining both commands:

git config alias.pullpush '!git pull && git push'

If the pull fails, the push won't be executed.


Finally, you can combine any sequence of command in a bash script, named

git-pullpush

(no extension, executable, stored in a folder referenced by the $PATH)

It would be a regular bash script (which works even on Windows, since it will be interpreted by the msys bash)

#!/bin/bash
# you can add any command you want
git pull && git push

And you would call it with git pullpush (like an alias)

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thank VonC. This is very good, but it is not what I wanted. There must be a step to commit and set message for my commit. – Ali Farhoudi Sep 21 '16 at 15:03
  • @AliFarhoudi That is why I mention in the script " you can add any command you want". That include any step you need. – VonC Sep 21 '16 at 15:05
3

When you want command2 to run if and only if command1 succeeds(basically returns 0), run using double ampersand sign &&, sandwiched between them:

command1 && command2 

And, to run command2 after command1 succeeds or even if fails, run using semicolon ;:

command1 ; command2 

I have used former one for git pull && git push and later one for git pull ; date

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • Thanks @saurav-sahu. This is helpful but I want to know if there is any way if I forgot to ```pull``` and just ran ```push```, it somehow alert me or run ```pull``` automatically. Currently it merges last commit of others with my commit. – Ali Farhoudi Sep 17 '16 at 07:59
  • Ok..I see..I will check and let you know...BTW space-separated alias like `git push` are not supported as per my knowledge. – Saurav Sahu Sep 17 '16 at 08:04
  • 1
    `git push` is already going to reject if you are not up-to-date with the remote. Just push. The act of pushing asks whether it is possible to push. If there's a reason why you can't push, you won't be able to push. Then you can worry about what to do. – Shaggy Sep 17 '16 at 08:04
  • yes, git push rejects code but when i pull after rejection, my teammate commit will be merged to my commit. – Ali Farhoudi Sep 21 '16 at 14:56