Git: push rejected non-fast-forward

I always get this when I am add a remote repository and I am trying to sync up branches. In order to resolve it, I pull from the repository and get any changes and then try to re-push.

$ git pull otherrepo
...
$ git push otherrepo localbranch

This will try to push the changes, but you should probably specify the remote branch as well if that still throws the non-fast-forward error.

$ git push otherrepo localbranch:remotebranch
Posted in Git

Git and Subversion Workflow – Part 2

I’ve been working with Git and Subversion together for some while, and I’ve been improving my work flow as I use it. Here’s the latest things I’ve worked out.

Stash popping with a dirty files
I use the stash command pretty frequently — often when I’m just working with a design but want to try something different and don’t want to play around with rebasing a commits — so I like my changes but want to put merge the code I had stashed. If you try:

$ git stash pop

You’ll get the error about working with dirty files. In order to remedy this, I fake it out, by pretending to want to add to the commit:

$ git add [files_i_changed]

Then, I do the stash pop and then reset so I don’t accidentally commit the code until I’m ready.

$ git reset HEAD

Appending commits for one commit to Subversion

A particular strength of Git is the ability to do multiple commits without sending everything to the server. (Okay, that’s the strength of any DVCS.) I usually like to send it all in one Subversion commit but I still want to keep a log of all my git commits, here is what I do. First, I’m working from a local branch that has all my git commits called ‘local_commits_for_issue_12345′.

Now, I will need to checkout the remote branch or the trunk that I want to commit to:

$ git checkout remotes/[branch or trunk]

And make a branch:

$ git checkout -b [some_new_remote_branch_name]

Then I merge:

$ git merge local_commits_for_issue_12345 --no-commit

Note, the no-commit part of the merge. Basically, Git will merge the code, and if it merges “successfully”, it will gracefully “fail” leaving the files that it merge in the filesystem until you do a git add and git commit and then git svn dcommit to send to Subversion. If it fails to merge successfully, well, you have to fix it like any other failed merge. As a side note, if you don’t include the no-commit, it’ll automatically commit the changes from your local branch.

Posted in Git

Git and Subversion Workflow – Part 1

Setting up git to use with subversion

Creating the initial subversion repository as a git repository, run this command:
$ git svn init -s [repository_url]

Then…
$ git svn fetch

This command will probably run for a while (especially large repositories) as it needs to find branches, tags, etc.

Switching to branches and creating local branches

This command will show you all your local and remote branches. Any remote branches will always have “remote/” before it.
$ git branch -a

This command will checkout your subversion code.
$ git checkout remotes/[subversion directory]

Then, to create a branch from that remote version.
$ git checkout -b [name_of_new_branch]

Committing to subversion

After some code changes, you can commit to whatever branch or trunk folder you’re current working off of by running the following command:

$ git svn dcommit

Cleaning up git

Run this command after you’ve had the repository running for awhile or if you run into some problems. This will do some compression and clean up of the git objects.
$ git gc

Adding a remote repository


$ git remote add [repository_name] [repository]

Then to add to it:


$ git push [repository_name] [branch]

Git and Subversion together

Subversion has been around for awhile as a version control system and I’ve been using it since it became a 1.0 application. Recently, I’ve begun using Git and found that I like it a lot more because it allows more finer control over my local code with things like local branching, fast branch switching, local commits, rewriting local commits before submit to main repository, and the stash.

So with the Git SVN bridge, you can pull from your subversion repository. Be forewarned though, if you have a large subversion repository with lots of revisions, it will take awhile to do the following because Git needs to process the revisions of the entire repository.
$ git svn clone [SVN_REPO_URL] --tags=tags --branches=branches --trunk=trunk

Now you have a local repository with changes with the above Git command. What I want though is a repository where I can make changes on more than one machine because I code on a work computer, a home desktop computer and a home laptop, I can create a personal repository that would sync all my computers but not commit changes to subversion yet. To do that I would create a personal Git repository, then add a remote site to the subversion clone from last command.
$ git add remote [NAME] [PERSONAL_REPO_SITE]

Push the subversion clone to my personal repository:
$ git push origin master

Once that’s done, I can pull from my local repository on any of my computers. Any changes that I want to commit to subversion, I go back to the computer with the subversion clone, update from my personal repository and commit those changes for everyone to see.
$ git svn dcommit

That’s it — that would be hard to do with Subversion alone and Git actually works the way I work. Sweet!

Reference:
Git SVN Crash Course
Git-SCM Book

Hardcopy Reference:
Pragmatic Version Control Using Git