Chapter 2. Git Basics

1.  You can get a Git project using two main approaches. The first takes an existing project or directory and imports it into Git. The second clones an existing Git repository from another server.

 

2.  If you're starting to track an existing project in Git, you need to go to the project's directory and type:

$ git init

This command creates a new subdirectory named .git that contains all of your necessary repository files—a Git repository skeleton. At this point, nothing in your project is tracked yet.

 

3.  If you want to start version-controlling existing files, you should probably begin tracking those files and do an initial commit:

$ git add *.c

$ git add README

$ git commit -m 'initial project version'

 

4.  If you want to get a copy of an existing Git repository, You clone a repository with git clone [url]   :

$ git clone git://github.com/schacon/grit.git

That creates a directory named grit , initializes a .git directory inside it, pulls down all the data for that repository, and checks out a working copy of the latest version. If you want to clone the repository into a directory named something other than grit , you can specify that as the command-line option.

 

5.  Git receives a copy of nearly all data that the server has. Every version of every file for the history of the project is pulled down when you run git clone .

 

6.  Git has a number of different transfer protocols you can use. You can use git:// protocol and http(s):// or user@server:/path.git , which uses the SSH transfer protocol.

 

7.  Each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot(or newly added to the staging area); they can be unmodified, modified, or staged. Untracked files are everything else—any files in your working directory that weren't in your last snapshot and aren't in your staging area. When you first clone a repository, all of your files will be tracked and unmodified because you just checked them out and haven't edited anything. As you edit files, Git sees them as modified, because you've changed them since your last commit. You stage these modified files and then commit all your staged changes, and the cycle repeats.


8.  The main tool you use to determine which files are in which state is the git status   command.

 

9.  In order to begin tracking a new file, you use the command git add :

$ git add README

If you run the git status command again, you can see that your README file is now tracked and staged. You can tell that it's staged because it's under the "Changes to be committed " heading. If you add a directory, the command adds all the files in that directory recursively.

 

10.  If you change a previously tracked file called benchmarks.rb and then run the git status command again, The benchmarks.rb file appears under a section named "Changed but not updated "—which means that a file that is tracked has been modified in the working directory but not yet staged. To stage it, you run the git add command.

 

11.   It turns out that Git stages a file exactly as it is when you run the git add command. If you modify a file after you run git add , you have to run git add again to stage the latest version of the file, otherwise when you run git commit , the version of the file as it was when you last ran the git add command is how it will go into the commit.

 

12.   You'll have a class of files that you don't want Git to automatically add or even show you as being untracked. These are generally automatically generated files such as log files or files produced by your build system. In such cases, you can create a file named .gitignore listing patterns to match them:

$ cat .gitignore

*.[oa]

The first line tells Git to ignore any files ending in .o or .a—object and archive files that may be the product of building your code. The second line tells Git to ignore all files that end with a tilde (˜).

 

13.   The rules for the patterns you can put in the .gitignore file are as follows:

  1)   Blank lines or lines starting with # are ignored.

  2)   Standard glob patterns work.

   3)   You can end patterns with a forward slash (/ ) to specify a directory.

   4)   You can negate a pattern by starting it with an exclamation point (!).

Glob patterns are like simplified regular expressions that shells use.

# a comment - this is ignored

*.a        # no .a files

!lib.a      # but do track lib.a, even though you're ignoring .a files above

/TODO    # only ignore the root TODO file, not subdir/TODO

build/    # ignore all files in the build/ directory

doc/*.txt  # ignore doc/notes.txt, but not doc/server/arch.txt

 

14.  To see what you've changed but not yet staged, type git diff with no other arguments. That command compares what is in your working directory with what is in your staging area.

 

15.   If you want to see what you've staged that will go into your next commit, you can use git diff --cached . (In Git versions 1.6.1 and later, you can also use git diff --staged , which may be easier to remember.) This command compares your staged changes to your last commit.

 

16.  Anything that is still unstaged—any files you have created or modified that you haven't run git add   on since you edited them—won't go into this commit. They will stay as modified files on your disk.

 

17.  The simplest way to commit is to type git commit . Doing so launches your editor of choice to edit your commit message. (This is set by your shell's $EDITOR environment variable, although you can configure it with git config ) The default commit message contains the latest output of the git status command commented out and one empty line on top. You can pass the -v option to git commit . Doing so also puts the diff of your change in the editor so you can see exactly what you did. Alternatively, you can type your commit message inline with the commit command by specifying it after a -m flag.

 

18.  Every time you perform a commit, you're recording a snapshot of your project that you can revert to or compare to later.

 

19.  Providing the -a option to the git commit   command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the git add part.

 

20.   The git rm   command removes a file from your staging area and also removes it from your working directory so you don't see it as an untracked file next time around. If you simply remove the file from your working directory, it shows up under the "Changed but not updated" (that is, unstaged) area of your git status output.

 

21.  If you modified the file and added it to the index (staged area) already, you must force the removal with the -f option. This is a safety feature to prevent accidental removal of data that hasn't yet been recorded in a snapshot and that can't be recovered from Git.

 

22.  To keep the file on your hard drive but not have Git track it anymore:

$ git rm --cached readme.txt

 

23.  You can pass files, directories, and file-glob patterns to the git rm   command:

$ git rm log/\*.log (removes all files that have the .log extension in the log/ directory.)

$ git rm \*˜   (removes all files that end with ˜ )

 

24.  Git has a mv command. If you want to rename a file in Git, you can run something like:

$ git mv README.txt README

this is equivalent to running something like:

$ mv README.txt README

$ git rm README.txt

$ git add README

Git figures out that it's a rename implicitly. If you run something like this and look at the status, you'll see that Git considers it a renamed file.

 

25.  git log can help you to view the existing commit history. By default, with no arguments, git log   lists the commits made in that repository in reverse chronological order.

 

26.   A huge number and variety of options to the git log   command are available:

    1)  options -p   shows the diff introduced in each commit. You can also use −2   , which limits the output to only the last two entries.

    2)  --stat option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. It also puts a summary of the information at the end.

    3)  --pretty option changes the log output to formats other than the default. –pretty= oneline   option prints each commit on a single line. –pretty=short , full , and fuller   options show the output in roughly the same format but with less or more information, respectively. --pretty format   allows you to specify your own log output format:

$ git log --pretty=format:"%h - %an, %ar : %s"

Formatting Options for the git log pretty Output


Option

Description of Output

%H

Commit hash

%h

Abbreviated commit hash

%T

Tree hash

%t

Abbreviated tree hash

%P

Parent hashes

%p

Abbreviated parent hashes

%an

Author name

%ae

Author e-mail

%ad

Author date (format respects the -date = option)

%ar

Author date, relative

%cn

Committer name

%ce

Committer e-mail

%cd

Committer date

%cr

Committer date, relative

%s

Subject

The oneline and format   options are particularly useful with another log option called --graph   . This option adds a nice little ASCII graph showing your branch and merge history, in which you can see your copy of the Grit project repository.

 

27.   Common git log Output Formatting Options:

Option

Description

-p

Show the patch introduced with each commit.

--stat

Show statistics for files modified in each commit.

--shortstat

Display only the changed/insertions/deletions line from the --stat command.

--name-only

Show the list of files modified after the commit information.

--name-status

Show the list of files affected with added/modified/deleted information as well.

--abbrev-commit

Show only the first few characters of the SHA-1 checksum instead of all 40.

--relative-date

Display the date in a relative format (for example, "2 weeks ago") instead of using the full date format.

--graph

Display an ASCII graph of the branch and merge history beside the log output.

--pretty

Show commits in an alternate format. Options include oneline , short , full , fuller , and format (where you specify your own format).

 

28.  The time-limiting options such as --since and --until are very useful:

$ git log --since=2.weeks

This command works with lots of formats—you can specify a specific date ("2008-01-15") or a relative date such as "2 years 1 day 3 minutes ago".

The --author option allows you to filter on a specific author, and the --grep option lets you search for keywords in the commit messages. Use --all-match   to match all filter otherwise the command will match commits with any. If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. This is always the last option and is generally preceded by double dashes (-- ) to separate the paths from the options.

Common git log Filtering Options


Option

Description

-(n)

Show only the last n commits.

--since, --after

Limit the commits to those made after the specified date.

--until, --before

Limit the commits to those made before the specified date.

--author

Only show commits in which the author entry matches the specified string.

--committer

Only show commits in which the committer entry matches the specified string.

 

 

29.  If you commit too early and possibly forget to add some files, or you mess up your commit message, you can run commit with the --amend option:

$ git commit --amend

This command takes your staging area and uses it for the commit. The same commit-message editor fires up, but it already contains the message of your previous commit. You can edit the message the same as always, but it overwrites your previous commit. This commit will replace the previous one.

 

30.  You can use "git reset HEAD <file> " to unstage a file.

 

31.  You can use "git checkout -- <file> " to discard changes in working directory.

 

32.  To see which remote servers you have configured, you can run the git remote   command. It lists the short-names of each remote handle you've specified. If you've cloned your repository, you should at least see origin   —that is the default name Git gives to the server you cloned from. You can also specify -v   , which shows you the URL that Git has stored for the short-name to be expanded to.

 

33.  To add a new remote Git repository as a short-name you can reference easily, run git remote add [shortname] [url] .

 

34.  To get data from your remote projects, you can run:

$ git fetch [remote-name]

The command goes out to that remote project and pulls down all the data from that remote project that you don't have yet. After you do this, you should have references to all the branches from that remote, which you can merge in or inspect at any time. The fetch   command pulls the data to your local repository—it doesn't automatically merge it with any of your work or modify what you're currently working on. You have to merge it manually into your work when you're ready.

 

35.  If you have a branch set up to track a remote branch, you can use the git pull [remote-repo] command to automatically fetch and then merge a remote branch into your current branch. By default, the git clone   command automatically sets up your local master branch to track the remote master branch on the server you cloned from. Running git pull   generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you're currently working on.

 

36.   When you have your project at a point that you want to share, you have to push it upstream:

$git push [remote-name] [branch-name]

If someone else pushed upstream and then you push upstream, your push will rightly be rejected. You'll have to pull down their work first and incorporate it into yours before you'll be allowed to push.

 

37.  If you want to see more information about a particular remote, you can use the git remote show [remote-name]   command.

 

38.  If you want to rename a reference, in newer versions of Git you can run git remote rename   [original-name] [new-name] to change a remote's short-name. If you want to remove a reference for some reason you can use

git remote rm [short-name] .

 

39.  Listing the available tags in Git is straightforward, just type git tag . You can also search for tags with a particular pattern:

$ git tag l v1.4.2.*

 

40.  Git uses two main types of tags: lightweight and annotated. A lightweight tag is very much like a branch that doesn't change—it's just a pointer to a specific commit. Annotated tags, however, are stored as full objects in the Git database. They're check-summed; contain the tagger name, e-mail, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG).

 

41.  The easiest way to create an annotated tag is to specify -a when you run the tag command:

$ git tag -a v1.4 -m 'my version 1.4'

 

42.  You can see the tag data along with the commit that was tagged by using the git show command:

$ git show v1.4

 

43.  You can also sign your tags with GPG:

$ git tag -s v1.5 -m  'my signed 1.5 tag'

 

44.  A lightweight tag is basically the commit checksum stored in a file—no other information is kept. To create a lightweight tag, don't supply the -a , -s , or -m option. If you run git show   on the tag, you don't see the extra tag information. The command just shows the commit.

 

45.  To verify a signed tag, you use git tag -v [ tag-name] . This command uses GPG to verify the signature. You need the signer's public key for this to work properly.

 

46.  To tag a past commit, you specify the commit checksum (or part of it) at the end of the command:

$ git tag -a v1.2 9fceb02

 

47.  The git push   command doesn't transfer tags to remote servers. You have to explicitly push tags to a shared server after you create them. This process is just like sharing remote branches—you can run git push origin [tagname] .

 

48.  You can also use the --tags option to the git push   command. This transfers to the remote server all of your tags that aren't already there.

 

49.  Download the Git source code, and look in the contrib/completion directory; there should be a file called git-completion.bash . Copy this file to your home directory, and add this to your .bashrc file:

source ˜/.git-completion.bash

If you want to set up Git to automatically have Bash shell completion for all users, copy this script to the /opt/local/etc/bash_completion.d directory on Mac systems or to the /etc/bash_completion.d/   directory on Linux systems. This is a directory of scripts that Bash will automatically load to provide shell completions.

 

50.  You can use git config to create alias for git command or external command:

$ git config --global alias.ci commit

git ci <----> git commit

$ git config –global alias.unstage  'reset HEAD --'

git unstage fileA <----> git reset HEAD fileA

$ git config --global alias.visual "!gitk"

git visual  <----> gitk

猜你喜欢

转载自seanzhou.iteye.com/blog/1427994