Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git pull hangs on SMB shared repository

When I run git pull, I get this:

edson$ GIT_TRACE=1 git pull -v
trace: exec: 'git-pull' '-v'
trace: run_command: 'git-pull' '-v'
trace: built-in: git 'rev-parse' '--git-dir'
trace: built-in: git 'rev-parse' '--is-bare-repository'
trace: built-in: git 'rev-parse' '--show-toplevel'
trace: built-in: git 'ls-files' '-u'
trace: built-in: git 'symbolic-ref' '-q' 'HEAD'
trace: built-in: git 'config' 'branch.master.rebase'
trace: built-in: git 'config' 'pull.rebase'
trace: built-in: git 'rev-parse' '-q' '--verify' 'HEAD'
trace: built-in: git 'fetch' '-v' '--update-head-ok'
trace: run_command: 'ssh' '[email protected]' 'git-upload-pack '\''xxxltd/xxxltd.git'\'''
trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet'
trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all'
trace: exec: 'git' 'rev-list' '--objects' '--stdin' '--not' '--all'
trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all'
From bitbucket.org:xxxltd/xxx
 = [up to date]      master     -> origin/master
 = [up to date]      blah -> origin/blah
trace: run_command: 'gc' '--auto'
trace: exec: 'git' 'gc' '--auto'
trace: built-in: git 'gc' '--auto'
trace: built-in: git 'rev-parse' '-q' '--verify' 'HEAD'
trace: built-in: git 'fmt-merge-msg'

But then it just hangs there.

The (bitbucket) repository is inside a windows 7 vmware machine. The repository is then shared via SMB to the host machine (mac osx). I'm running git pull (macports) on the host.

If I run git pull (msysgit) inside the vm, it works fine.

Any clue?

like image 963
Edson Medina Avatar asked Jan 07 '14 13:01

Edson Medina


People also ask

Why git pull is not working?

Not enough information for Git to work with As the error message states: you will have to let Git know what remote branch it should use to track with the current local branch. Doing this will allow you to simply run git pull and Git will know where to bring new data from.

What is git pull fastforward?

Fast forward merge can be performed when there is a direct linear path from the source branch to the target branch. In fast-forward merge, git simply moves the source branch pointer to the target branch pointer without creating an extra merge commit.

Does git pull affect working directory?

Yes, as the pull docs say: git pull runs git fetch with the given parameters and calls git merge to merge the retrieved branch heads into the current branch. With --rebase, it runs git rebase instead of git merge. A merge or rebase will affect your working tree.

Does git pull affect remote?

The short answer is simple: no, the remote-tracking branch remains unaffected.


2 Answers

In the Git source, there seems to be a infinite loop in Git's fmt-merge-msg function when the repo sits in a SMB share while being accessed from Mavericks. The only way I've been able to fix this is by doing doing a process that doesn't involve automatic merging.

git pull is essentially a git fetch && git merge all in one command. If you try and do a git fetch into your current branch when there have been changes, you may run into an issue where the git fetch fails.

The way that I've fixed this issue is to fetch the remote branch into a temporary local branch and them merge that temp branch into your working branch. See the following which details trying to fetch the latest changes from your origin/master into your current working branch master.

  1. Fetch the latest changes from origin master into a local branch called master_merge_tmp. git fetch [<remote loc>] [<remote branch>]:[<local branch>] allows you to fetch the latest changes without invoking fmt_merge_msg automatically and you can target a different local destination branch:

    git fetch origin master:master_merge_tmp
    
  2. Merge the master_merge_tmp branch into master:

    git merge master_merge_tmp
    
  3. Perform some cleanup by deleting the remote branch mater_merge_tmp:

    git branch -D master_merge_tmp
    

Alternatively you could create a helper function to automate the steps above. You can place this in your .bashrc or .zshrc:

# Workaround for fmt-merge-msg issue on Mavericks w/SMB repo
# gfm [<remote>] [<remote branch>]
function _git-fetch-merge() {
  local remote="$1"
  local branch="$2"
  local tmp_branch="${2}_merge_tmp"
  git fetch $remote $branch:$tmp_branch
  git merge $tmp_branch
  git branch -D $tmp_branch
}
alias gfm="_git-fetch-merge"

Now from the terminal you can do the following:

_git-fetch-merge origin master

Or you can use the alias:

gfm origin master

If you are working with a remote upstream branch:

gfm upstream master
like image 93
psyrendust Avatar answered Nov 09 '22 05:11

psyrendust


Apple switched to SMB2 with Mavericks and it's not working so well for quite a few people. As an alternative, here's a more permanent fix you can apply instead of the temporary one of cifs://:

To force all connections to be SMB1:

Open A terminal window paste in the following line followed by the return key (should be all on one line):

echo "[default]" >> ~/Library/Preferences/nsmb.conf; echo "smb_neg=smb1_only" >> ~/Library/Preferences/nsmb.conf

What the command does:

Creates a file called nsmb.conf in your home directory at the path ~/Library/Preferences/nsmb.conf. Adds directives to force SMB connections to use the SMB1 protocol. This is slower but stable.

How to remove the workaround:

Open a terminal window paste in the following at the prompt and then hit the return button:

rm ~/Library/Preferences/nsmb.conf

Notes: ( source )

Its a good idea to restart your mac before trying to connect to your storage again. This will clear any hung SMB processes from previous attempts to connect to your storage before implementing this workaround.


EDIT: Commenter replied "it wasn't helpful" — not the best choice of words, but you get the idea.

like image 27
l'L'l Avatar answered Nov 09 '22 06:11

l'L'l