Everything tagged git (3 posts)

git: what to do if you commit to no branch

Using git, you'll sometimes find that you're not on any branch. This usually happens when you're using a submodule inside another project. Sometimes you'll make some changes to this submodule, commit them and then try to push them up to a remote repository:

ed$ git commit -m "My excellent commit"
[detached HEAD d2bdb98] My excellent commit
3 files changed, 3 insertions(+), 3 deletions(-)
ed$ git push origin master
Everything up-to-date
ed$ git commit -m "My excellent commit"
[detached HEAD d2bdb98] My excellent commit
3 files changed, 3 insertions(+), 3 deletions(-)
ed$ git push origin master
Everything up-to-date

Er, what? Everything is not up to date - I just made changes! The clue is in the first part of the commit response - [detached HEAD d2bdb98]. This just means that we've made a commit without actually being on any branch.

Luckily, this is easy to solve - all we need to do is checkout the branch we should have been on and merge in that commit SHA:

ed$ git checkout master
Previous HEAD position was d2bdb98... My excellent commit
Switched to branch 'master'
ed$ git merge d2bdb98
Updating 88f218b..d2bdb98
Fast forward
ext-mvc-all-min.js | 2 +-
ext-mvc-all.js | 2 +-
view/FormWindow.js | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
ed$ git checkout master
Previous HEAD position was d2bdb98... My excellent commit
Switched to branch 'master'
ed$ git merge d2bdb98
Updating 88f218b..d2bdb98
Fast forward
ext-mvc-all-min.js | 2 +-
ext-mvc-all.js | 2 +-
view/FormWindow.js | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)

Once we got onto the master branch, we just called git merge with the SHA reference for the commit we just made (d2bd98), which applied our commit to the master branch. The output tells us that the commit was applied, and now we can push up to our remote repository as normal:

ed$ git push origin master
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 692 bytes, done.
Total 6 (delta 4), reused 0 (delta 0)
To git@github.com:extmvc/extmvc.git
88f218b..d2bdb98 master -> master
ed$ git push origin master
Counting objects: 11, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 692 bytes, done.
Total 6 (delta 4), reused 0 (delta 0)
To git@github.com:extmvc/extmvc.git
88f218b..d2bdb98 master -> master

This had me puzzled for a while so hopefully it'll save someone banging their head against a nearby wall.

Continue reading

When Git tells you it failed to push some refs

I received an unhelpful error while trying to push to a repository on Github today:

git push
To git@github.com:user/repo.git
! [rejected] branchname -> branchname (non-fast forward)
error: failed to push some refs to 'git@github.com:user/repo.git'
git push
To git@github.com:user/repo.git
! [rejected] branchname -> branchname (non-fast forward)
error: failed to push some refs to 'git@github.com:user/repo.git'

In case you ever have the same problem, all you have to do is a quick git pull first, then you can carry on as normal. Easy when you know how...

Continue reading

Git clone vs Git submodule

Having recently made the switch from svn to git, I wanted to achieve what svn externals did (and what Piston did better). Turns out this is pretty simple, for example to get rails on edge:

cd your_git_dir
git submodule add git://github.com/rails/rails.git vendor/rails
cd your_git_dir
git submodule add git://github.com/rails/rails.git vendor/rails

A couple of other default submodules you'll want:

git submodule add git://github.com/dchelimsky/rspec.git vendorpluginsrspec
git submodule add git://github.com/dchelimsky/rspec-rails.git vendorpluginsrspec-rails
git submodule add git://github.com/dchelimsky/rspec.git vendorpluginsrspec
git submodule add git://github.com/dchelimsky/rspec-rails.git vendorpluginsrspec-rails

What submodule does is to check out the submodules as their own repositories, so they are tracked independently of the repository you made them submodules of. The submodules you have are tracked in the .gitmodules file, which might look something like this:

[submodule "vendorrails"]
path = vendor/rails
url = git://github.com/rails/rails.git
[submodule "vendor/plugins/rspec"]
path = vendor/plugins/rspec
url = git://github.com/dchelimsky/rspec.git
[submodule "vendor/plugins/rspec-rails"]
path = vendor/plugins/rspec-rails
url = git://github.com/dchelimsky/rspec-rails.git
[submodule "vendorrails"]
path = vendor/rails
url = git://github.com/rails/rails.git
[submodule "vendor/plugins/rspec"]
path = vendor/plugins/rspec
url = git://github.com/dchelimsky/rspec.git
[submodule "vendor/plugins/rspec-rails"]
path = vendor/plugins/rspec-rails
url = git://github.com/dchelimsky/rspec-rails.git

Or at least that's how it should look, Windows seems to mess this up into looking something like the following:

[submodule "vendorrails"]
path = vendor\rails
[submodule "vendorrails"]
url = git://github.com/rails/rails.git
[submodule "vendorpluginsrspec"]
path = vendor\plugins\rspec
[submodule "vendorpluginsrspec"]
url = git://github.com/dchelimsky/rspec.git
[submodule "vendorpluginsrspec-rails"]
path = vendor\plugins\rspec-rails
[submodule "vendorpluginsrspec-rails"]
url = git://github.com/dchelimsky/rspec-rails.git
[submodule "vendorrails"]
path = vendor\rails
[submodule "vendorrails"]
url = git://github.com/rails/rails.git
[submodule "vendorpluginsrspec"]
path = vendor\plugins\rspec
[submodule "vendorpluginsrspec"]
url = git://github.com/dchelimsky/rspec.git
[submodule "vendorpluginsrspec-rails"]
path = vendor\plugins\rspec-rails
[submodule "vendorpluginsrspec-rails"]
url = git://github.com/dchelimsky/rspec-rails.git

Note especially that you need to remove the 's and replace all 's with /'s. If you don't git will give a fail message like:

fatal: bad config file line 2 in .gitmodules
No submodule mapping found in .gitmodules for path 'vendor/plugins/attachment_fu'
fatal: bad config file line 2 in .gitmodules
No submodule mapping found in .gitmodules for path 'vendor/plugins/attachment_fu'

I don't know why it's doing that, maybe it's something I'm doing wrong but you'll need to tidy it up to make it look more like the first example in order for it to work properly.

One final thing to be aware of is that when you clone onto a new machine you'll need to run the following commands:

git submodule init
git submodule update
git submodule init
git submodule update

This will initialise the submodules that are referenced in the .gitmodules file, then pull them down. By default cloning doesn't seem to do that.

Continue reading