68

I tried to put a series of GIT commands that I always use continuously togeter as batch files so that I don't repeat myself too much. For example, I have this batch file called update_repo_branch.bat to update a local repo and synch a branch with the remote branch:

@echo off
if(%1) == () goto end
if(%2) == () goto end
cd %1
git checkout %2
git fetch origin
git merge oring/%2
:end

Good to be lazy, but what I found is that when a GIT command is finished, it seems to send an exit flag back to terminate whatever is running. Therefore, using a batch file to exectute them all in one go simply doesn't work. Any idea how to work around it?

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
Pok
  • 1,521
  • 1
  • 13
  • 20

4 Answers4

84

I'm not sure if this is true for all Windows git packages, but at least some use a git.cmd script as a wrapper around the actual git executables (for example git.exe). So when you're batch file uses a git command, Windows is actually running another batch file.

Unfortunately, when one batch file invokes another, by default it 'jumps' to the invoked batch file, never to return (this is for compatibility with ancient MS-DOS command processors or something).

You can solve this problem in a couple ways:

  1. invoke git in your batch files using the call command to run the git.cmd batch file and return back to yours:

    call git checkout %2
    call git fetch origin
    rem etc...
    
  2. invoke git in your batch file using the .exe extension explicitly to avoid the git.cmd batch file altogether. For this to work, you might need to make sure that you have your path and other environment variables set the way git.exe expects (that seems to be what git.cmd does in msysgit):

    git.exe checkout %2
    rem etc...
    
Joey
  • 344,408
  • 85
  • 689
  • 683
Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 6
    Since `call` does nothing unexpected with normal programs that's actually a nice way to completely avert this, regardless of what `git` they use (didn't even know there were that many). – Joey Mar 23 '11 at 06:40
  • 2
    +1. The behaviour described by the OP is very likely to confirm the fact that `git` is indeed a batch script. An `exe` program is hardly expected to behave like that. And I agree with Joey, `CALL` wouldn't harm even if the program did turn out to be an `exe`. – Andriy M Mar 23 '11 at 08:24
  • 2
    You unzipped my heart with your solution! Thanks a zillion! – Basil Musa Dec 11 '14 at 01:07
4

Assuming you are using msysGit as your Git client you might actually want to use Bash scripts for this. You could place a bash function in your ~/.bashrc (~ is usually your C:\Users\- see here) as follows

update_repo_branch() {
    if [ $# != "2" ]; then
        echo "Usage: update_repo_branch REPO BRANCH" 1>&2
        return 1
    fi

    cd $1
    git checkout $2
    git fetch origin
    git merge origin/$2
}

You can then run update_repo_branch myrepo cool-branch from the mysysGit shell.

Of course, this won't be accessible from cmd.exe. You will only be able to use it within the msysGit cygwin shell.

Community
  • 1
  • 1
Jim Mitchener
  • 8,835
  • 7
  • 40
  • 56
2

As i see from your example you're actually trying to sync your local branch 'branchname' with origin/branchname

For this you don't need any additional scripting, you just have to use git pull instead of sequence git checkout branchname; git fetch origin; git merge origin/branchname

take a look at the docs about tracking branches in git and their benefits.

generally speaking if you have a repo layout like this:

git branch -a
...
master
dev1
dev2
remotes/origin/master
remotes/origin/dev1
remotes/origin/dev2

And your dev1 and dev2 branches are tracking branches for origin/dev1 and origin/dev2 correspondingly then you just need to execute in repository:

git pull

This command will effectively sync up all you local tracking branches with remote ones.

for more see here:

Git pull docs

Git remote branches and tracking branches (Progit book)

Eugene Sajine
  • 8,104
  • 3
  • 23
  • 28
0

Create a notepad file and paste the below content and save with .bat extension.

This script can be use for setting up git first time in a project.

!echo off
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin <YOUR_REPO_URL>
git push -u origin main
pause