git - version control system

links: |- index -|- commands -|- home -|

in page : alphabetic list
in page: add branch checkout clean clone commit config delete format-patch log merge pull reset stash status tag update
 examples [1] [2] [3] [4] [4b] [5] [5b] line endings end

git

2011-01-06: Added a few more items to the page... as my use, and understanding?, of git grows ;=))

2009: git is the latest source repository tool. See http://git-scm.com/ for further details. This page only documents some of my personal git usage and experiences - quite minimal really... anyway, as the git home page states - "Git is used for version control of files, much like tools such as Mercurial, Bazaar, Subversion, CVS, Perforce, and Visual SourceSafe.", and perhaps others. The author of git is Linus Torvalds...

Naturally, git provides extensive online help, support - see Git User's Manual, but still, some of the 'concepts' can take while to sink in ;=() And if you are specifically interested in FlightGear GIT repositories, then there is a very good wiki page for that - FG-Wiki-Git

Git Installation (in WIN32)

2011-02-01: From http://code.google.com/p/msysgit/ I downloaded and installed git version 1.7.3.1.msysgit.0 from the file
01/02/2011 12:42 12,256,826 Git-1.7.3.1-preview20101002.exe
but as of 2011-02-04 note there is now a Git-1.7.4-preview20110204.exe, so re-installed that (2011-02-08) over the previous version with no trouble.

Running this executable installs 'git', by default, in C:\Program Files\Git, and if you allow it, the installer will add C:\Program Files\Git\cmd to the PATH environment variable.

git clone - downloading a source

To download, clone, an online repository :-

~$ git clone URL [target]

will download all the source in the particular repository, creating a 'master' git repository locally. Most of the following git commands will be done in the source directory created.

If no target directory is given, then a name from the remote repository will be used, like 'source' for both FG and SG, so it is usually better that you provide your own <target> directory...

In some cases, like FG/SG source repos, this will be a 'next' repository... The command git branch -a will display the local and remote branches, with an asterisk (*), indicating the current active branch.

See ??? for more...

top


git pull - update a source

When the online source is changed or updated :-

~/target $ git pull [-v]

will update the local source to that of the online repository 'master' branch.

However, if you are presently on a 'branch', like say 'next', then -

~/target $ git pull origin next

will do the trick... that is $ git-pull <options> <repository> <refspec>...

From my file .git\config, I can see 'origin' listed as -
[remote "origin"]
   fetch = +refs/heads/*:refs/remotes/origin/*
   remote = origin
with the url being
  url = git://gitorious.org/fg/fgdata.git
in this FGDATA case...

Unless you do changes to the code locally, and want to pass it back to the repository, the above commands, clone and pull, are all that is generally required. Note these are sometimes written as git-clone and git-pull...

If the repository is a very active one, then it is sometimes good to follow either of these commands with a -

~/target $ git status

to check if there are some 'updates' not yet committed. To clear these -

~target $ git add *
~target $ git commit -a -m "Clear updates"

should help... now a git-status may show you nn commits ahead of 'next', or 'master' ;=))

In simple terms, git-pull fetches from, and merges with, another repository or a local branch

synopsis
git pull [<options>] [<repository> [<refspec>]]...

Runs git fetch with the given parameters, and calls git merge to merge the retrieved head(s) into the current branch. With --rebase, calls git rebase instead of git merge.

See ??? for more...

top


git status - get a view of the changes

After changes are made to the local source, use :-

~/target $ git status

will show all the 'changed but not updated', and 'untracked', for new files'

This command will suggest 'git add <file>...', to update or include what will be later 'committed'...

I have learnt to try to remember to always do a 'git status' before updating from the remote repository... locally tracked 'changed' files can stop the 'merge' part of the 'git pull', and kill the process, reporting 'merge' problems... which can take extra time to resolve...

See ??? for more...

top


git stash - save or restore local changes

After changes are made to the local source, use :-

~/target $ git stash [save]

to save any local changes, and return the local directory to a clean state

Then after syncing the local branch to the remote, and possibly switching to a different local branch

~/target $ git stash restore

will restore the local changes previously stashed (saved) into the current local branch.

Examples:

Pulling into a dirty tree

When you are in the middle of something, you learn that there are upstream changes that are possibly relevant to what you are doing. When your local changes do not conflict with the changes in the upstream, a simple git pull will let you move forward.

However, there are cases in which your local changes do conflict with the upstream changes, and git pull refuses to overwrite your changes. In such a case, you can stash your changes away, perform a pull, and then unstash, like this:

$ git pull
 ...
file foobar not up to date, cannot merge.
$ git stash
$ git pull
$ git stash pop

See ??? for more...

top


git add - add a file, or file-pattern

As the command 'git add --help' shows, the command adds the current content of new or modified files to the index, thus staging that content for inclusion in the next commit. Thus if you CHANGE any 'tracked' file in the repo, 'git add <file>' will be the next step, to update what will be committed...

Synopsis:
git-add [-n] [-v] [-f] [-i] [-p] [-u] <file-pattern>

Options:
 -n, --dry-run = just show if they exist
 -v, --verbose = be verbose
 -f = allow otherwise ignored files
 -i, --interactively = run in interactive mode
 -p, --patch = similar to interactive, but patch is invoked on each file-pattern before exit
 -u = update only file git knows about. if no paths are specified, all tracked files are updated

See ??? for more...

top


git commit - store contents, and log message

As the command 'git commit --help' shows, the command stores the current contents of the index in a new commit along with a log message describing the changes you have made.

Synopsis:
git-commit [-a | --interactive] [-s] [-v] [-u] [(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
                  [--allow-empty] [--no-verify] [-e] [--author <author>]
                  [--clenaup=<mode>] [--] [[-i | -o ]<file>...]

Options:

-a, --all  = to automatically stage files that have been modified and deleted, but not new files
-c or -C <commit>  = take existing commit object, and reuse log and author information. -C no editor, -c edit
-F <file>  = take commit message from given file
--author <author>  = override name used. Use "A U Thor <author@example.com>" format.
-m, --message <msg>  = commit message
--amend  = amend, correct the last commit message (if not yet pushed).
-e, --edit  = further edit the message
-s, --signoff  = add sign-off-by-line at end of commit message
-t, --template <file>  = use given file as initial version of the commit message
--no-verify  = bypass the pre-commit and commit-msg hooks
--allow-empty  = bypasses some safeties...
--cleanup=<mode>  = verbatim, whitespace, strip, and default message handling
-i, --include  = usually not, unless a conflicting merge
-u, --untracked-files  = show all untracked
-v, --verbose  = show diff (-u) between HEAD and what is committed
-q, --quiet  = suppress summary message
--  = do not interpret any more arguments as options
<file>  = commit the named file(s)

See ??? for more...

top


git config - get and set repository or global options

You can query/set/replace/unset options with this command. The name is actually the section and the key separated by a dot, and the value will be escaped, like say $ git config --get core.filemode ...

Synopsis:
git config [<file-option>] [type] [-z|--null] name [value [value_regex]]
git config
[<file-option>] [type] --add name value
...
git config [<file-option>] [-z|--null] -l | --list
...

Where the optional <file-options> is one of --system, --global or --file which specify where the values will be read from or written to. The default is to assume the config file of the current repository, .git/config unless defined otherwise with GIT_DIR and GIT_CONFIG.

Some important values are :-

user.email
Your email address to be recorded in any newly created commits. Can be overridden by the GIT_AUTHOR_EMAIL, GIT_COMMITTER_EMAIL, and EMAIL environment variables.

user.name
Your full name to be recorded in any newly created commits. Can be overridden by the GIT_AUTHOR_NAME and GIT_COMMITTER_NAME environment variables.

These 2 are important only due to the fact that they are added to the 'format-patch' output and the defaults, if they are not set, seem to by just 'user' for the name, and 'machine_name.com' as the email domain, which looks a little strange in a patch. But on the other hand, when doing patches, these values can have been over-ridden on the command line when doing the $ git commit ... shown above, via the --author <author> command.

See ??? for more...

top


git format-patch - To generate a set of patches

After you have made files changes in your local repository, you can use $ git diff  [--options ...] to show the changes between two 'trees', but after you have done $ git add [options] files... and $ git commit [options] files on your changed files, then $ git format-patch [options...] is used to output patch files between your local repository and the master.

Synopsis:
git format-patch [-k] [(-o|--output-directory) <dir> | --stdout] [--no-thread | --thread[=<style>]] [(--attach|--inline)[=<boundary>] | --no-attach] [-s | --signoff] [-n | --numbered | -N | --no-numbered] [--start-number <n>] [--numbered-files] [--in-reply-to=Message-Id] [--suffix=.<sfx>] [--ignore-if-in-upstream] [--subject-prefix=Subject-Prefix] [--cc=<email>] [--cover-letter] [<common diff options>] [ <since> | <revision range> ]

In general this will write a set of numbered patch files, one file for each commit, to the -o <dir>, which should be a directory outside the repository, formatted to resemble UNIX mailbox, and the output of this command is convenient for e-mail submission using $ git am [options...]. See comments above concerning the name, email address and message, which are usually set during the $ git commit [options...] file process.

Examples:

$ git format-patch -o ..\patches origin/next   # note, fg 'next'
$ git format-patch -o ..\patches origin/master # note, sg-cs 'master'

See ??? for more...

top


git clean - Remove untracked files from the working tree

Synopsis:
git clean [-d] [-f] [-n] [-q] [-e <pattern>] [-x | -X] [--] <path>

Cleans the working tree by recursively removing files that are not under version control, starting from the current directory. Adding -x, to not use the ignore rules, allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset) to create a pristine working directory to test a clean build.

See ??? for more...

top


git branch

To list, create, or delete branches... git branch without arguments will list the current branches, placing a asterisk next to the currently active branch

Synopsis:
git branch [--color[=<when>] | --no-color] [-r | -a] [-v [--abbrev=<length> | --no-abbrev]] [(--merged | --no-merged | --contains) [<commit>]]
git branch [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
git branch (-m | -M) [<oldbranch>] <newbranch>
git branch (-d | -D) [-r] <branchname>...

Description:

With no arguments, existing branches are listed and the current branch will be highlighted with an asterisk. To 'change the active branch, see git checkout.

Option -r causes the remote-tracking branches to also be listed, and option -a shows both. The -v (verbose) option will add a an abbreviated SHA1, and commit subject line, for each head, along with relationship to upstream branch (if any). If given twice, print the name of the upstream branch, as well (if any).

@REM call git branch -t -l next origin/next

Delete Branches

Working with branches is quite a fun way to collaborate with git, but then comes the time after the new 'test' branch has been tested, and fully merged with 'master', or 'next', how to DELETE it.

Delete Local Branch

$ git branch -d test, or
$ git branch -d -r origin/test

Delete Remote Branch

This has to be done with authentication, so is a bit obtuse
$ git push origin :test, or
$ git push <ur> :test

Reference: See ??? for more.

top


git checkout

Checkout a branch or paths to the working tree

SYNOPSIS

git checkout [-q] [-f] [-m] [<branch>]
git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
git checkout --patch [<tree-ish>] [--] [<paths>...]

DESCRIPTION

Updates files in the working tree to match the version in the index or the specified tree. If no paths are given, git checkout will also update HEAD to set the specified branch as the current branch. git checkout -f <file> will revert the file to match the index. Or git checkout -- <file>  to discard changes in working directory.

@REM call git checkout next

Detached HEAD

It is sometimes useful to be able to checkout a commit that is not at the tip of one of your branches. The most obvious example is to check out the commit at a tagged official release point, like this:

$ git checkout v2.6.18

or to check out per a previous date

$ git checkout master@{"Mon Dec 31  2007"}
  

See http://linux.die.net/man/1/git-checkout for more...

top


git reset

Reset current HEAD to the specified state

SYNOPSIS

git reset [-q] [<commit>] [--] <paths>...
git reset --patch [<commit>] [--] [<paths>...]
git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]

DESCRIPTION

To 'reset' one or more files back to its original state use 'checkout', like say git checkout -- path/to/file/to/restore

In the first and second form, copy entries from <commit> to the index. In the third form, set the current branch head (HEAD) to <commit>, optionally modifying index and working tree to match. The <commit> defaults to HEAD in all forms.

As the FG-Wiki-Git states, concerning updating a repository, 'reset' can be used to clear any local changes made -

  1. Run git reset --hard to revert any local changes. Note: this will delete all local changes! If you made local changes, make sure to backup those first, outside the local repository directory! Or, better, learn to commit your changes to your local git repository.
  2. Run git pull and let it update, this can take a while

See ??? for more...

top


git merge

synopsis
git merge [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]... [--[no-]rerere-autoupdate] [-m <msg>] <commit>...
git merge <msg> HEAD <commit>...

One item spoken about often today with regard to SG/FG/... git, http://gitorious.org/fg, is a 'merge request'. This is where the developer has (a) made a private clone on gitorious; (b) cloned (pulled) that to his/her local machine; (c) updated/changed the local repository; (d) then 'git push' the changes back to his/her gitorious clone. Now the developer can use a 'Request merge' button, for someone with write access to the master repository to 'merge' the changes back into the master.

See ??? for more...

top


git tag

Get a list of current tags -

$ git tag -l

The output on my local FlightGear 'next' clone

C:\FGCVS\flightgear\source>git tag -l
2.2.0-rc1
last-cvs
master-20100117
master-20100125
v2.0.0
v2.0.0-bits
v2.0.0-rc1
v2.0.0-rc2
v2.0.0-rc3
v2.0.0-rc4

To create a new (local) tag

$ git tag <new-tag-name>

Then after an update, like $ git pull origin next, a difference can be viewed with

$ git diff <new-tag-name> next > ../diff.patch

See ??? for more...

top


git log

Out put the list of commits, with lots of information

commit fb52b013f0e5e3371a1a82e0cbb51d3bbfd18e6d
Author: ThorstenB <brehmt@gmail.com>
Date:   Fri Apr 15 21:34:44 2011 +0200

    Clear OSG object cache on scenery reload
    Scenery reload (menu: Debug-> Reload Scenery) also needs to clear
    the OSG object cache, otherwise scenery isn't really reloaded from disk.

commit dc76290d6e7d2f24d6c352d8f9da4b0f9f1e5f40
Author: ThorstenB <brehmt@gmail.com>
Date:   Fri Apr 15 00:20:06 2011 +0200

    Minor file mode issue.

commit 7f5a0e35184677c21f1eafdfbe6438eb644cdbff
Author: ThorstenB <brehmt@gmail.com>
Date:   Fri Apr 15 00:15:18 2011 +0200

    Adrian Musceac: #303, YASim solver settings
    The internal solver of YASim which computes drag and lift
    coefficients now actually uses the values configured in
    the XML input file for approach fuel, cruise fuel and cruise
    glide angle.
...

To get a potentially BIG list of the commits made, try

$ git log --abbrev-commit --pretty=oneline > ..\templog2.txt

Sample...

fb52b01 Clear OSG object cache on scenery reload Scenery reload (menu: ...
dc76290 Minor file mode issue.
7f5a0e3 Adrian Musceac: #303, YASim solver settings The internal solver...
d88dcba Add fgpanel to the automake build system
f44dd24 Initial commit of the fgpanel code
1456635 Fixed minor memory leak on joystick reload.
...

See ??? for more...

top


Examples

Example 1: root is $HOME/fg4

1. git download

~/fg4$ git clone git://mapserver.flightgear.org/terragear-cs/
  ... download will proceed ...
~/fg4$
~/fg4$ cd terragear-cs
~/fg4/terragear-cs$

2. modify the source, in this case dem.cxx... and write modified file...

~/fg4/terragear-cs$ kate src/Lib/DEM/dem.cxx &
~/fg4/terragear-cs$

3. git status

~/fg4/terragear-cs$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#      modified: src/Lib/DEM/dem.cxx
#
# Untracked files:
#
#      src/Lib/DEM/dem.cxx~
no changes added to commit (use "git add" and/or "git commit -a")
~/fg4/terragear-cs$

4. git add

~/fg4/terragear-cs$ git add src/Lib/DEM/dem.cxx
~/fg4/terragear-cs$

5. git status

~/fg4/terragear-cs$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#      modified: src/Lib/DEM/dem.cxx
#
# Untracked files:
#
#      src/Lib/DEM/dem.cxx~
~/fg4/terragear-cs$

git commit

~/fg4/terragear-cs$ git commit -m "Allow non-integer stpes\n\n \
For ASCII DEM with say 0.75 step" --author "Geoff McLane <ubuntu _at_ geoffair _dot_ info> \
 src/Lib/DEM/dem.cxx
Created commit d778530: Allow non-integer steps\n\nFor ASCII DEM with say 0.75 step
 1 files changed, 2 insertions(+), 2 deletions(-)
~/fg4/terragear-cs$

And then if you want to send a patch to the maintainers of the repository, use 'git format-patch :-

~/fg4/terragear-cs$ git format-patch -o patches origin/master
patches/0001-Allow-non-integer-steps-n-nFor-ASCII-DEM-with-say-0.patch
~/fg4/terragear-cs$

produced the following patch ;-

From d77853082d9f5c59ee971c89e367a3ad84fe81b2 Mon Sep 17 00:00:00 2001
From: Geoff McLane <ubuntu _at_ geoffair _dot_ info>
Date: Mon, 13 Apr 2009 17:04:07 +0200
Subject: [PATCH] Allow non-integer steps\n\nFor ASCII DEM with say 0.75 step
---
 src/Lib/DEM/dem.cxx |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Lib/DEM/dem.cxx b/src/Lib/DEM/dem.cxx
index 2835d2b..e98e9e1 100644
--- a/src/Lib/DEM/dem.cxx
+++ b/src/Lib/DEM/dem.cxx
@@ -470,8 +470,8 @@ TGDem::write_area( const string& root, SGBucket& b, bool compress ) {
     }
     fprintf( fp, "%d %d\n", (int)min_x, (int)min_y );
-    fprintf( fp, "%d %d %d %d\n", span_x + 1, (int)col_step, 
-            span_y + 1, (int)row_step );
+    fprintf( fp, "%d %f %d %f\n", span_x + 1, col_step, 
+            span_y + 1, row_step );
     for ( int i = start_x; i <= start_x + span_x; ++i ) {
        for ( int j = start_y; j <= start_y + span_y; ++j ) {
            fprintf( fp, "%d ", (int)dem_data[i][j] );
-- 
1.5.4.3

  I still have to work out how to get a new line into the message...

Then, if you have made a mistake, in say the message, like I have, then

~/fg4/terragear-cs$ git reset --soft HEAD^

will put dem.cxx back into the 'staged' state, ready for a 'better' git commit action, and if you want to completely unwind the action, then :-

~/fg4/terragear-cs$ git reset HEAD dem.cxx

will put dem.cxx back in the 'Changed but not updated:' stage, ready to try 'git add' again ;=))

On the next try I put the 'message' in a file with beginning 'subject' line, followed by two blank lines, then a brief explanation, and used :-

~/fg4/terragear-cs$ git commit \
  -F patches/dem.cxx.txt src/Lib/DEM/dem.cxx
Created commit 3c14ab6: Allow non-integer steps.
 1 files changed, 2 insertions(+), 2 deletions(-)
~/fg4/terragear-cs$

and this worked fine, so is the way-to-go ;=)) It seems to now remember my email address, and put both the subject and the explanation line in the 'diff', from 'git format-patch --stdout origin/master ... so all seems well and good...

2010-12-20: Results of a $ git pull on gitorious simgear source -

C:\FGCVS\simgear\source>git pull
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 3), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From git://gitorious.org/fg/simgear
   b9a34b1..ae9757b  next       -> origin/next
Your configuration specifies to merge with the ref 'next'
from the remote, but no such ref was fetched.

What can be the problem? The .git\config contains -

C:\FGCVS\simgear\source>type .git\config
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
        hideDotFiles = dotGitOnly
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git://gitorious.org/fg/simgear.git
[branch "next"]
        remote = origin
        merge = refs/heads/next

top


Example 2:

From: Anders Gidenstam to FlightGear developers discussions Date: Sat, 5 Feb 2011 15:14:42 +0100 (CET)

Q: How can I update my FlightGear development code base (which was created a few months ago) from git?

A: Simple -

1., If NO changes made in local branch, then just

$ git pull

should do the right thing. It will also 'work' even if you have local committed changes, but will make the local history messy, and thus the remote history if such changes are later pushed back to the remote.

2. If you do have local branch changes you want to keep, then 'git rebase' will keep them on top, so

(a) Commit local changes

$ git status - to show what files have been modified
$ git add file1 file2 etc - adds the files to be committed
$ git commit -m "description" - create a commit with the changes added
$ git format-patch -o path/to/patches origin/master
The last is optional, to keep a 'diff' record.

(b) Fetch the latest stuff from the main repository.

$ git fetch

(c) Rebase your local branch on top of the latest official state.

$ git rebase origin/next - for FG & SG sources
$ git rebase origin/master - for FG base data

(d) If you get conflicts you can drop your local conflicting commit by

$ git rebase --skip
or resolve the conflicts, git add the changed files shown in a 
git status, and continue the rebase with -
$ git rebase --continue

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:

$ git branch my-branch.20110205 my-branch

He also noted "Win32 git works well from Windows powershell", but I have noted some occasional problems using a standard windows command prompt, and tend to generally use the Git Bash shell.

top


Example 3:

from : ThorstenB, flightgear development list, Tue, 08 Feb 2011

Q: Dealing with 'branches' created in the remote repository. FG/SG git has created a branch 'releases/2.2.0', and since the git 'next' blanch has moved on, it is no longer a valid test for the pending releases/2.2.0 branch. How to have both branches compliable, so that BOTH branches can be tested, separately?

A: To create a new local 2.2.0 branch, for both SG and FG -

$ git checkout -b releases/2.2.0 origin/releases/2.2.0

Then to switch between 'next' and the 2.2.0 branches

$ git checkout next
and
$ git checkout releases/2.2.0

Each branch is kept up-to-date using 'git pull', and each is rebuilt normally (e.g. 'make && make install').

Alternatively, there are also advanced methods using separate, cloned repositories, if you want to be able to run both version without the need for switching and recompiling. Some more details of this are in the flightgear-devel archives.

More on Dealing with Branches

A release blanch 2.2 has been created on the remote repository, and you want to get it locally...

# create local 2.2.0 branch
 git branch releases/2.2.0 origin/releases/2.2.0
# switch branch
 git checkout releases/2.2.0
# merge current next into 2.2.0 release (ok only right _now_, since there are no 
# simgear commits _yet_ which mustn't go to the release - otherwise pick&apply 
# patch manually)
 git merge next
# push local branch to remote branch...
 git push git@gitorious.org:fg/simgear.git releases/2.2.0:releases/2.2.0
# back to next (don't forget! :) )
 git checkout next

top


Example 4:

from : Yves, on using gitorious.org/fgx, June 2011

This is a method, similar to the above, of creating 'test' branches, modifying the 'test' branch, pushing the tested, functional 'test' branch back to the remote git so others can check it out, merge it with master, and possibly delete the 'test' branch.

// Assumes a clone has been done of <remote repo>, on 'master' branch.
// check the local branches that exist... the asterisk indicates the active
$ git branch
*master
// create local 'test' branch, and switch to it...
$ git checkout -b test
// now a branch check should show
$ git branch
 master
*test
// create and/or modify files in the 'test' branch
$ <create file1.cxx> - this is a new file
$ <edit file2.cxx> - this is modifying an existing file
// check what files have been modified in 'test'
$ git status
# On branch test
# Changes to be committed:
#  (use "git reset HEAD <file>..." to unstage
#
#  new file:  file1.cxx
#
# Changed but not updated:
#  (use "git add <file>..." to update what will be committed)
#  (use "git checkout -- <file>..." to discard changes in working directory)
#
#  modified:  file2.cxx
#
# Untracked files:
# ... not interesting ...
// 'add' these new and modified files
$ git add file1.cxx
$ git add file2.cxx
// 'commit' these new and modified files, with a message
$ git commit -m "fixed something" file1.cxx file2.cxx
// finally 'push' files to the remote, for others to checkout, test...
$ git push git@<remote repo> test

The perhaps after the remote 'test' has been tested, it can be merged with the remote master. At that point both the remote and local 'test' branches could be deleted, since the results would be in master.

This is an example making a small change to one file, and pushing to FGx next branch -

// modify the file
...\fgx-next> <EDIT src/xobjects/xprocess.cpp>
// check the status
...\fgx-next> git status
# On branch next
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: src/xobjects/xprocess.cpp
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# fgx-build-desktop
   no changes added to commit (use "git add" and/or "git commit -a")
// add the modify file
...\fgx-next> git add src/xobjects/xprocess.cpp
// check the status
...\fgx-next> git status
# On branch next
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: src/xobjects/xprocess.cpp
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# fgx-build-desktop/

// commit the modify file, with a message
...\fgx-next> git commit -m "Fix process ID in windows" src\xobjects\xprocess.cpp
   [next a9e26cc] Fix process ID in windows
   1 files changed, 7 insertions(+), 3 deletions(-)

// check the status
...\fgx-next> git status
# On branch next
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# fgx-build-desktop/
   nothing added to commit but untracked files present (use "git add" to track)

// push, with authentication, the modification to remove next
...\fgx-next> git push git@gitorious.org:fgx/fgx.git next
Enter passphrase for key '/c/D&S/<username>/.ssh/id_rsa':  <enter pass>
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 501 bytes, done.
Total 5 (delta 4), reused 0 (delta 0)
=> Syncing Gitorious... [OK]
To git@gitorious.org:fgx/fgx.git
   3bc3b0b..a9e26cc next -> next

All done...

top


Example 5:

Updating a local branch to same as that on the remote. In this case I had made all the changes in an Ubuntu local geoff2, which had then been pushed to the remote geoff2. However had already made a minor change in the local airportsimport.cpp file, so had to 'undo' this later, to get the desired merge local with the remote

fgx> git checkout -b geoff2
M       src/airports/airportsimport.cpp
Switched to a new branch 'geoff2'
fgx> git pull // as sometimes, this did nothing!
fgx> git pull // or as sometimes, a stupid error!
fatal: C:\Program Files\Git/libexec/git-core/git-pull cannot be used without a working tree.
fgx> git pull
fgx> git pull // but keep insisting, and...
remote: Counting objects: 13, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
From git://gitorious.org/fgx/fgx
 * [new branch]      geoff2     -> origin/geoff2
You asked me to pull without telling me which branch you
want to merge with, and 'branch.geoff2.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository>  <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "geoff2"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.
// all that looks interesting, but try...
fgx> git pull . geoff2
From .
 * branch            geoff2     -> FETCH_HEAD
There are no candidates for merging among the refs that you just fetched.
Generally this means that you provided a wildcard refspec which had no
matches on the remote end.
// make sure I am on the desired branch...
fgx> git branch
* geoff2
  geoffw2
  master
// then 'merge' with origin/<branch>...
fgx> git merge origin/geoff2
Updating 3e4bd6b..2fae60c
error: Your local changes to the following files would be overwritten by merge:
        src/airports/airportsimport.cpp
Please, commit your changes or stash them before you can merge.
Aborting
// UGH! As usual, ALWAYS check the 'status' before a 'merge'...
fgx> git status
# On branch geoff2
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   src/airports/airportsimport.cpp
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       fgx-build-desktop/
no changes added to commit (use "git add" and/or "git commit -a")
// so DISCARD the local changes...
fgx> git checkout -- src/airports/airportsimport.cpp
// then complete a SUCCESSFUL merge...
fgx> git merge origin/geoff2
Updating 3e4bd6b..2fae60c
Fast-forward
 src/airports/airportsimport.cpp |    2 +-
 src/panes/timeweatherwidget.cpp |    5 +++++
 2 files changed, 6 insertions(+), 1 deletions(-)

Got there in the end ;=))

Another workflow perspective, syncing with remote next, and working in a local branch, re-sync next, merge local, and push to remote next...

$ git pull origin next            // sync with remote
$ git checkout [-b] geoff4        // switch to a local branch 'geoff4'
$ git merge next                  // merge in HEAD, but already done if -b
$ <EDIT> <file1>                  // make changes in local
$ git add <file1>                 // stage change for commit
$ git commit -m "message" <file1> // commit changes to local
$ git checkout next               // switch back to HEAD
$ git pull origin next            // sync again with next
$ git merge geoff4                // merge in the local changes
$ git push origin next            // send to gitorious

 

top


Line Endings

This excellent page seems to say it ALL - http://help.github.com/dealing-with-lineendings/  - BUT in case that page ever disappears, then it is repeated here, with my big thanks to github help, and the author...

Dealing with line endings

Line endings… the scourge of every Windows-based developer that tries to mingle with linux- or mac-based developers. Though most modern text editors can handle both newline types without issue, git is not as graceful.

For more info on the issue see Wikipedia.

Mac and Linux users, you don’t get to sit this one out

Although you might think you’re immune to CRLF-ended files on mac and linux, you are not. It is possible to download files from an external source that use CRLF, and thus commit them into your repo. To be safe, you should set your config to convert line endings on commit so they are always LF in the repo:

$ git config --global core.autocrlf input

I just cloned and git says files have changed!

So, you just cloned a repo on a Windows box, and it says that all of your files have been modified. Huh? You’ve not touched anything yet! What the…

The problem is that your core.autocrlf option is likely not enabled. This setting tells git to convert the newlines to the system’s standard when checking out files, and to LF newlines when committing in. To turn it on use this command:

$ git config --global core.autocrlf true

Once this is set, you need to reset your repos. The best way to do this is wipe out your working tree (all the files except the .git directory) and then restore them:

# Remove everything from the index
$ git rm --cached -r .
# Re-add all the deleted files to the index
# You should get lots of messages like: 
# "warning: CRLF will be replaced by LF in <file>."
$ git diff --cached --name-only -z | xargs -0 git add
# Commit
$ git commit -m "Fix CRLF"
# If you're doing this on a Unix/Mac OSX clone then optionally
# remove the working tree and re-check everything out with 
# the correct line endings.
$ git ls-files -z | xargs -0 rm
$ git checkout .

Thanks to Charles Bailey’s post on stackoverflow for this solution.

Moving forward

Now that you’ve standardized the newlines in your repo things should be better. However, every person that touches your repo should turn autocrlf on, even non-Windows users. It is possible for them to bring in code from an outside source that has CRLF newlines, and you don’t want them saved into the repo like that.

For more details on the core.autocrlf setting see the git-config documentation.

top


Resolving Conflicts

It’s common to get stuck with conflicts, due to deviations between your site’s files and those in the remote repository. If you run into a sub-module error during the git pull step, you’ll need to stash your changes:

git stash
git pull origin master
git stash apply

Note that you may have to individually resolve conflicts with git add or git rm during the git stash apply step.

top


There is a _LOT_ more to be said about 'git', but that's it for now ;=))

top


Alphabetic List

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z top

A: add
B: branch
C: checkout clean clone commit config
D:  delete
E:  
F: format-patch
G:  
H:  
I:  
J:
K:
L: log
M: merge
N:  
O:  
P: pull
Q:
R: reset
S: status stash
T: tag
U:  update
V:
W:  
X:  
Y:
Z:  

top


checked by tidy  Valid HTML 4.01 Transitional

class a class b class c class d class e class f class o class v class t