Git pull hangs on SMB shared repository
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.
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
.
Fetch the latest changes from
origin master
into a local branch calledmaster_merge_tmp
.git fetch [<remote loc>] [<remote branch>]:[<local branch>]
allows you to fetch the latest changes without invokingfmt_merge_msg
automatically and you can target a different local destination branch:git fetch origin master:master_merge_tmp
Merge the
master_merge_tmp
branch intomaster
:git merge master_merge_tmp
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