Hi

i created a cheatsheet and howto for using git for those svn-only-users
of you :)

Please read it fully through, it should contain everything you need for
everyday use plus just a tiny bit more.

If you have no experience with git, I recommend you to try this with a
small private repository:

git init --bare --shared repo.git
git clone repo.git alice
git clone repo.git bob

now, alice and bob should be both clones which behave just like the repo
you get when you clone the muse-git repository.

Try committing, pushing, pulling, branching, merging. You could walk
through the complete examples one time, I think that covers pretty much
everything.

Have fun with git :)




@Joachim and others: if you find any mistake, please complain loudly :)

Greetings
flo
conventions
===========

>>> denotes blocks of text that shall be emphasized.

Shell commands will be prefixed with $ or %, both are common shell prompt
delimiters. While

>>> $ echo foo

is to be executed on your computer,

>>> % echo foo

will be typed in on Alice's computer.

possible confusion
==================

svn checkout is git clone!
git checkout is something else (more like svn switch)!



With git, you don't checkout things from a central server. You *clone* the
repository, having a complete own repo. The "central server" we have our
"central git" on is not really "central" or special in any way. It is ONLY by
convention that we treat this repo as the authoritative copy. Technically,
there is no difference.



svn commit will just commit all changed files. Git commit WILL NOT.
git has a concept of "staged" and "unstaged" contents. Git commit will only
commit staged content; to stage your changes, you can run

>>> $ git add file.c

on every changed file, which gives you a fine control of your commits. Note
that when first staging a file, then changing this file, then the new changes
are still not staged! git add again.

Usually, to get a similar behaviour to svn commit, just use

>>> $ git commit -a

This will automatically stage all changes (but not auto-add new files, as with
svn.)




git commit will not talk to the network! When you git commit, nobody will see
this, unless you run

>>> $ git push



setting up prerequisites
========================

**** ssh keys
     --------

Do you use ssh-keys? If not, do use them!

>>> $ ssh-keygen

Answer the questions. The default location is fine, just press enter. If you
want to be prompted for a password for this key, enter a passphrase.

The use of ssh-agent greatly simplifies using a passphrase: Once you have set
up ssh-agent (which your distro might have already done for you), it is only
neccessary to *once* run

>>> $ ssh-add

after a reboot of your machine. This will prompt you for the passphrase once
and then remember it.


You should add this key to your sf.net account. Go to this site:

>>> https://sourceforge.net/account/ssh

In a terminal, type:

>>> $ cat ~/.ssh/id_rsa.pub   # don't forget the .pub!

Then copy-and-paste the output, store the key, and wait some time.


**** setting up git
     --------------

First, don't worry: Git is actually pretty forgiving about mistakes, and tells
you exactly what you have to type in order to fix them.

Set your name and e-mail address using:

>>> $ git config --global user.name "Your Name"
>>> $ git config --global user.email "[email protected]

Recommended: if you only want to push the branch which is currently checked
out (pull will only pull the checked out branch anyway, so this makes git more
intuitive), then set:

>>> $ git config --global push.default simple

(Recent git versions will complain about this setting anyway, if it's
missing.)


cloning the repository ("svn checkout")
=======================================

this will fetch the whole repository (don't worry, git is much better at
compression than svn) and set up a working copy on your local machine(s).

>>> $ git clone ssh://[email protected]/p/lmuse/muse muse-git


migrating your SVN working copy
===============================

for the svn branch you have uncommitted changes in:

>>> $ cd path/to/svn/working/copy
>>> $ svn diff > /tmp/something.diff
>>> $ cd path/to/muse-git
>>> $ git checkout corresponding_branch
>>> $ patch -p0 --dry-run < /tmp/something.diff

Now hope there are not too much errors. If there are, try -p1, or you might be
in the wrong directory. If there are some failed hunks, --merge might help
(this generates a svn-like merge). If everything looks fine enough, remove
the --dry-run option to actually apply the patch.

If there is more than one unclean branch, you might want to consider
committing these changes, or use some of the tools in git-contrib, or clone
the repo twice.



Congratulations :)!


using git -- cheatsheet
=======================

"a clean working copy" = git status outputs no staged or unstaged changes
"trunk" in svn = "master" in git
"upstream" = anyone who is not you. Especially the repository on sf.net

svn checkout =                  git clone
svn checkout a certain branch = git checkout branchname

svn commit = git commit -a, then git push
             or git add, then git commit and git push


git push might fail, if there were concurrent changes on upstream. In this
case, you must

>>> $ git pull

first, and possibly fix conflicts. Then git push again.


svn update   = git pull (you might need a clean working copy,
                         git will tell you)
svn status   = git status
svn add/rm   = git add/rm
svn help ... = man git-...

svn copy ^/trunk ^/branches/newbranch = git checkout -b newbranch
(this will check out this new branch immediately. You need a clean working
 copy for this!)

svn merge ^/trunk                          = git merge master
svn merge --reintegrate ^/branches/feature = git merge feature

list all local branches  = git branch
list all remote branches = git branch -r
list all branches        = git branch -a

svn diff = git diff

svn revert = git reset (read git-reset(1) before! This will cause a loss of
data, possibly more than you'd expect if called with wrong options!)

git-stash(1) is handy.



Branching model
===============

Git is all about branching. Branches are super easy and fast to use, don't eat
up much space. Use them!

master is the mainline branch which is expected to be always in a known good
state. Please don't develop features in master.

When you want to develop a feature or a bugfix which will take you more than
one (1!) commit, please develop this in a branch.

Example: let's assume you want add support for flying lamas to MusE:
         since this can be implemented very quickly, we don't push the
         developing branch with upstream.

>>> # make sure your working copy is clean, possibly git-stash away your
      changes
>>> $ git checkout -b flying_lamas   # you are now in this branch.
>>> $ vim some_file.c
>>> $ git add some_file.c
>>> $ git commit                     # remember that upstream still does not
                                     # see your commit unless you git-push
>>> $ vim file.c
>>> $ git commit                     # now the feature is done
>>> $ git checkout master
>>> $ git merge flying_lamas         # this will merge the changes introduced
                                     # by the flying_lamas branch into master.
                                     # possibly fix merge conflicts and follow
                                     # git's instructions
done :)

Example: Let's assume you want to port muse to QT5, which is a looong task.
         You want to share your progress with upstream, you want that others
         can collaborate.

>>> $ git checkout -b qt5
>>> $ git push -u origin qt5         # inform upstream about this branch
                                     # the '-u origin' is required for git
                                     # pull and push later.
>>> $ vim
>>> $ git commit -a
>>> repeat.

now, today's coding session is over. You want to share your progress with
upstream.

>>> $ git push                       # remember, if this fails, just git pull
                                     # and retry.


Now Alice decides to help you with the new feature. So Alice checks out your
new qt5 branch:

>>> % git pull                       # git must talk to the repo server
                                     # to find out about the new qt5 branch.
>>> % git checkout qt5               # there is no -b option. If Alice has a
                                     # fairly recent git, this will
                                     # automatically set up the branch so that
                                     # git push/pull will work.
git will respond with something like this:
>>> Branch qt5 set up to track remote branch qt5 from origin.

>>> % vim, commit, ...

Alice takes a coffee break and has a short talk with you. You're telling her
that Bob also has committed stuff onto this branch.

so Alice pulls these changes using

>>> % git pull                       # this will generate a merge commit

and works on. Finally she does

>>> % git push


Time has passed, and master has been developed on.
While on the qt5 branch,

>>> $ git checkout master
>>> $ git pull                       # get an up-to-date master
>>> $ git checkout qt5
>>> $ git merge master               # don't forget pushing the result!

will get all the fixes from master into qt5 as well.
(Don't forget to push the merge to upstream)

Time has passed even more, the move to qt5 is done :)

>>> $ git checkout master
>>> $ git merge qt5
>>> $ git push

yay! The new branch is reintegrated into the old master.




Git is an extremely flexible tool with many possibilities. Please don't use
all of them, some of them are risky or don't fit into this workflow.

E.g., try to avoid the use of git rebase. This will rebase your commits which
have been diverged from master some time ago with the up-to-date master HEAD.
This results in a linearized history, as you would get with SVN. But you're
manipulating your history here (this will horribly break if you have already
pushed the changes), and you haven't tested each rebased commit, right ;)?

A nonlinear history like that:
            o-------o---------o    <- You are committing changes, but not
           /                   \      pushing immediately
-----o----o                     o  <- This merge commit unions your and Alice's
           \                   /      pushed commits
            o----o-----o------o    <- Same thing does Alice.
is perfectly fine.

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may
_______________________________________________
Lmuse-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/lmuse-developer

Reply via email to