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.
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
