FlightGear Git: Difference between revisions

Jump to navigation Jump to search
13,527 bytes removed ,  1 June 2013
Move additional commands/tips to FlightGear Git: tips
(→‎Resetting the repository: http://flightgear.org/forums/viewtopic.php?f=18&p=182309#p182309)
(Move additional commands/tips to FlightGear Git: tips)
Line 1: Line 1:
{{FlightGearGitOn}}
{{Git}}
 
'''Git''' is a version control system, used by the [[FlightGear]] project to store all of the files required to build FlightGear. This includes all the programs, the data (e.g. [[aircraft]]), supporting tools, etc. Git tracks updates to every file, as developers from around the world work together concurrently to create new versions.
'''Git''' is a version control system used by the [[FlightGear]] project to store all of the files required to build the FlightGear, including all the programs, the data (e.g. [[aircraft]]), supporting tools, etc. Git tracks updates to every file, as developers from around the world work together concurrently to create new versions.


While new FlightGear features and additions are in development, they are available from Git before they are available in the standard release version. Using Git allows users to build the newest possible version of FlightGear from the latest source files, to experiment with new aircraft or other features. However, it's not a beginner's tool. Using Git can expose the user to unstable features that show ugly error messages, or crash the computer.  
While new FlightGear features and additions are in development, they are available from Git before they are available in the standard release version. Using Git allows users to build the newest possible version of FlightGear from the latest source files, to experiment with new aircraft or other features. However, it's not a beginner's tool. Using Git can expose the user to unstable features that show ugly error messages, or crash the computer.  
Line 294: Line 293:
  git cherry-pick b049e1d # repeat this for each commit you'd like to push
  git cherry-pick b049e1d # repeat this for each commit you'd like to push
  git push}}
  git push}}
== Supporting information ==
=== Some more helpful commands ===
;<code>git help</code>
;<code>git help [command]</code>
;<code>git apply</code>
: apply a patch to files and/or to the index http://www.kernel.org/pub/software/scm/git/docs/git-apply.html
;<code>git checkout -f</code>
: may be used to throw away any local changes to the ''working tree''. Use with care, as any option that name is <tt>-f</tt> or <tt>--force</tt>, and only after reading <code>git checkout help</code>!
;<code>git pull</code>'''
: may be used for future updates
=== git remote - adding remote repositories ===
Now, before anyone unnecessarily goes through the pain of cloning fgdata
again, you just need to add the git URL to your new personal
clone at gitorious as a remote in your local fgdata clone to be able to
push to gitorious.
For example:
'''git remote add my-fgdata g...@gitorious.org:~andersg/fg/anders-fgdata.git'''
Stores the URL to my fgdata clone at gitorious under the name my-fgdata in  my local git clone of fgdata. (You want the gitorious SSH URL for your repository)
'''git push my-fgdata my-branch:master'''
Pushes the local branch named my-branch to my-fgdata (i.e. my clone of fgdata at gitorious) where the branch will be named master.
=== Switching to a remote branch ===
You can create a local version of a remote branch with "git branch releases-2.2.0 origin/releases-2.2.0"or "git checkout -b releases-2.2.0
origin/releases-2.2.0". Git doesn't create a local branch automatically. It exists locally as a remote branch. Create a local branch based on it
with '''git branch -t -l my-2.2.0 origin/releases/2.2.0'''
=== git pull ===
git pull will also work if you have committed local changes but will make your local history messy (and the official history too if your changes
are ever merged back into the official history). If you don't care about the messyness of your local history read no further than point 1 below and use git pull without hesitation :)
If you do have changes you want to keep I'd recommend using git rebase to  keep them "on top" of the official work:
1. First commit your changes to your local branch.
<pre>
git status                - show you what files you have modified.
git add file1 file2 etc  - adds the files you want to commit
git commit                - creates a commit with the changes you have added.
</pre>
2. Fetch the latest stuff from the main repository.
<pre>
git fetch
</pre>
3. Rebase your local branch on top of the latest official state.
For the FlightGear and SimGear sources this would be
<pre>
git rebase origin/next
</pre>
For fgdata it is
<pre>
git rebase origin/master
</pre>
4. If you get conflicts you can drop your local conflicting commit by
<pre>
git rebase --skip
</pre>
or resolve the conflicts, git add the changed files and continue the rebase with
<pre>
git rebase --continue
</pre>
(Use of git status is needed here to see which files are in conflict).
As an additional safe-guard you may create a name for your previous work
before you rebase so that you can easily recover it if the rebase goes
bad. Assuming your branch is called my-branch the following command
creates a back-up point:
<pre>
git branch my-branch.20110205  my-branch
</pre>
=== Merging Topic Branches ===
You want to merge your branch back into master. merge is the right word:
* git checkout master
* git merge newidea
done. If the merge creates conflicts, git will tell you so. To fix them, simply edit the files and add them to the index (git add fixed_file) and when you are done do a git commit. A merge usually creates a new commit anyway, since it's a new version of your source tree.
If your newidea branch is nice and tidy and a straight continuation of your current master branch (i.e. they have not diverged) you can just  merge the newidea branch into master (if they have not diverged it will just be a fast-forward of the master branch).
You can create a new branch to keep track of your old master point first if you like:
'''git branch old-master master'''
git branch -h  or --help will show many useful options to git branch e.g. for creating, renaming and deleting branches.
As long as you don't rewrite the history you can always create a new branch starting at any old commit so there is no particular need to
create such branches before you need them (except maybe to help remembering where that point was).
If the branches have diverged I would consider cherry-pick over the commits from the newidea branch into master (if they are not very many)
and perhaps also tidy them up with using interactive rebasing before publishing the new master state. This is particularily useful if master is
a public branch that receives commits from other developers - it avoids the rather ugly multiple levels of merges we see in e.g. fgdata. (See also git rebase).
gitk --all is a very useful tool to see where your different branches are in the history and how they relate to each other.
While on the master branch:
'''git merge newidea'''
=== Resolving Conflicts ===
Basically, you have to resolve your conflicts at that point if you want to keep your commit. Even if you merged your changed branch (e.g. with git pull) rather than rebasing it you'd get the conflicts.
* git status            to check which files are in conflict.
* git add <files>        to register the state you want them to have.This may include cleaning out merge conflict from text files before adding them.use git checkout local-weather -- the/file to restore your version and git checkout master -- the/file to restore the upstream version.
* git rebase --continue  to continue the rebase.
For your own local work I recommend committing it in small logical units - that makes it easier to use git rebase --skip to remove local edits when
they become obsolete due to upstream updates.
Btw. if you don't have any particular need to checkout the master branch just
<pre>
  git fetch origin/master
  git rebase origin/master
</pre>
on the local-weather branch will do.
But do remember to use origin/master rather than just master in git diff and git checkout -- some/file commands in that case, since your local
master branch will not be updated by fetch and rebase.
=== git merge vs. rebase ===
Each rebase moves your local commits to be on-top of all upstream commits.
For example, my local SimGear branch currently looks like this:
git log output:
<pre>
commit 4087b34f7ebbdb54b62afb205dc2e1ca225dc68b
Author: Anders Gidenstam <and...@gidenstam.org>
Date:  Tue Mar 29 22:44:53 2011 +0200
    Experimental Nasal GC work: Added a GC thread.
commit d94d1a907d6ec001ab9ba497bc03aaeff55f923c
Author: Anders Gidenstam <and...@gidenstam.org>
Date:  Sun Oct 3 16:59:50 2010 +0200
    Turn the creation of a variable without the var keyword an error in
Nasal.
commit c7c3fae5c2cd21cf81e7a94911568adba926f680
Author: ThorstenB <bre...@gmail.com>
Date:  Sat May 7 19:40:01 2011 +0200
    Also remove visual_enviro.cxx from the VC90 build.
</pre>
That is my two local commits appear as later than any upstream commit,  although they are "older" (as seen by their dates).
This is the effect of the rebase. If I had merged my branch with the upstream branch instead of rebasing it on top of the upstream branch my
commits would have been somwhere way down in the history.
However, note that each rebase creates new commits since the commit ID is a consequence of the history preceding the commit. The old "copies" of my
commits from previous rebases are no longer part of my local branch.
=== Keeping topic branches in sync with upstream ===
Any time someone pushes a change to the gitorious repository here is the approximate procedure to update my local clones/branches (this is the git
replacement for the old cvs update command):
<pre>
cd "primary-fgdata"
git pull
<error> - oops I have a branch checked out currently
git checkout master
<error> - oops commit any changes in the current branch
- git diff
- git commit
git checkout master (try again, it works)
git pull (now it works)
git checkout "primary-branch"
git merge master (to sync the upstream changes with my own "wip" branch)
</pre>
But this is just in the main fgdata clone, Now cd over to my --local branch clone.
<pre>
cd "../fgdata-clone"
git pull (merge upstream changes from my local master repository that have
been merged into the master branch in the previous step.)
git diff (see what I changed locally)
git commit (commit my local changes)
git push (push these changes back into the primary branch in my original
clone of the gitoriious repository)
<error> - oops I have the branch checked out in my primary local  repository
- cd "../fgdata-primary"
- git checkout master
- cd ../fgdata-clone"
git push (now it works!)
</pre>
Woohoo, everything should now be consistent and in sync and all the upstream changes should be fully merged.
=== Tracking a release branch ===
git branch -t -l release/2.6.0 origin/release/2.6.0
git checkout -b release/2.6.0
=== Messed up branches ===
It's worth experimenting with "git reflog" in situations like this. That tracks a list of HEAD references in strict chronological order
(i.e. what has HEAD been in the past, not what commits were done).
In cases where you've completely mucked up the revision history, you can look at this to see what you were doing before, recover the commit ID, and do a reset --hard to that.
"Backing out" is done with git reset --hard last_good_commit. Often the name of the last good commit is HEAD^, the last commit. However, after a botched
merge it is good to verify that with git log or graphically with gitk.
A merge commit has two parent commits (leaving aside octopus commits). If you are not happy with the results of the merge, usually you want to revert
back to the parent that was on your branch. The reflog can be useful for checking this, but usually the parent of the botched merge on your branch is HEAD^.
If you've pushed a commit to a public repo and then it later turns out that the commit wasn't a good idea, then you want "git revert" which creates the
reverse patch for a given commit. However, if you make a real hash out of a public repo you may still want git reset.
Backing it out might be a bit tricky, but you can rename your messed up branch out of the way easily with git branch -m oldname newname.
To cherry-pick commits from your other repository into a branch you first fetch the branch you want to pick, e.g.
'''git fetch theOtherRepro.git theotherbranch:suitableName/theotherbranch'''
Or just '''theotherbranch:suitableOthername'''
Then you can inspect the commits on it with '''git log -u theOtherRepro/theotherbranch'''
And finally cherry-pick the one you want with '''git cherry pick <commitID>'''
It's a good idea to always use a clean local copy (e.g. git branch -t mrClean origin/master)  of origin/master to cherry-pick commits to before pushing to origin, and leave that branch around since the next time you just need to check it out, do '''git pull''' which will be a clean fast forward and '''cherry-pick''' and push again.
=== Resetting the repository ===
If you find yourself having constant trouble with GIT and being contstantly asked to "rebase" your commitments, please don't delete anything, instead follow AndersG's instructions below.
If you have a local clone of fgdata you have everything at hand - starting over is just creating a new local branch that tracks master, e.g.:
<pre>
git branch my-new-master origin/master
git checkout my-new-master
</pre>
And update it to latest with (I recommend using --rebase in the future since that will keep your local commits after all up stream commits):
'''git pull --rebase'''
Use
<pre>
git status
</pre>
and
<pre>
git diff
</pre>
to investigate what ever uncommitted changes you may have in your tree. If you want to throw all such changes away, use '''git reset --hard'''
Or you can use '''git stash''' to save them for later.
If you have an old branch with your work and want to reapply selected commits to the new one, '''git cherry-pick''' is a useful command.
=== Updating old FGData gitorious clones ===
If you haven't updated your gitorious clone in a while, so that it significantly diverges from the main fgdata repository, pushing all changes would eat up lots of resources (bandwith, CPU) - thus, it is generally better to back up all important data/branches, and then delete your gitorious clone, to start over with a fresh clone - that way, you'll save tons of bandwidth and time. Cloning fgdata only takes a fraction of the time that would be required to push hundreds of megabytes of data separately, this is because cloning fgdata is a "local" operation for gitorious - so that bandwith is not the bottleneck.
=== Git tutorials and resources ===
* Git [http://git-scm.com/documentation documentation and tutorials]
* Git Basics [http://schacon.github.com/git/gittutorial.html]
* The [http://zrusin.blogspot.com/2007/09/git-cheat-sheet.html Git Cheat Sheet] and the [http://jan-krueger.net/development/git-cheat-sheet-extended-edition Git Cheat Sheet Extended Edition]
* [http://wiki.github.com/bogolisk/egg Egg], a cool Git emacs mode.
* A guide to [http://nathanj.github.com/gitguide/ using Git on Windows]
* [http://kylecordes.com/2008/04/30/git-windows-go/ Git on Windows Go!] (Setting up msysgit on Windows)
* [http://sourceforge.net/projects/qgit qgit - interactive git repository viewer and frontend]
* Additional [[Resources WRT running git on Win32]]


== Related content ==
== Related content ==
Line 577: Line 301:
[[Category:Core developer documentation]]
[[Category:Core developer documentation]]
[[Category:FlightGear]]
[[Category:FlightGear]]
[[Category:Git]]


[[fr:FlightGear et Git]]
[[fr:FlightGear et Git]]

Navigation menu