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.
有两种方法获取一个Git管理的工程。第一种方法是把一个现存的工程导入到Git管理的仓库中。第二种是从服务器复制一个现存的工程。
Initializing a Repository in an Existing Directory
If you’re starting to track an existing project in Git, you need to go to the project’s directory and type:
用git init来管理一个现存的项目
git init
This 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.(See Chapter 10 for more information about exactly what files are contained in the .git direcotry you just created.)
这样会建立一个.git子目录,.git包含了git仓库所需要的所有文件。直到这时,在你的项目中还没有任何东西被管理。
if you want to start version-controlling existing files (as opposed to an empty directory),you should probably begin tracking those files and do an initial commit. You can accomplish that with a few git add commands that specify the files you want to track, followed by a git commit:
git add *.c
git add LICENSE
git commit -m "initial project version"
We’ll go over what these commands do in just a minute. At this point,you have a Git reposigory with tracked files and an initial commit.
Recording Changes to the Repository
You have a bona fide Git repository and a checkout or working copy of the files for that project.You need to make some chages and commit snapshots of those changes into your repository each time the project reaches a state you want to recored.
Remember that each file in your working direcotry can be in one of two states:tracked or untracked. Tracked files are fiels that were in the last snapshot;they can be unmodified,or staged.Untracked files are every-thing else - any files in your working directory that were not in your last snapshot and are not in your working direcotry that were not in your last snapshot and are not in your staging area.When you first clone a repository, all of your eiles will be tracked an unmodified because you just checked them out and haven't edited anything.
As you edit files, Git sees them as modifed,because you've chaged them since your last commit.You stage these modified files and then commit all your staged chages, and the cycle repeats.
Checking the Status of Your Files
The main tool you use to determine which files are in which state is the git status command.If you run this command directly after a clone, you should see something like this:
git status
On branch master
nothing to commit, working directory clean
This means you have a clean working direcotry - in other words, there are no tracked and modified files.Git also doesn’t see any untracked files,or they would be listed here.Finally ,the command tells you which branch you’re on and informs you that it has not diverged from the same branch on the server.For now,that branch is alway “master”,which is the default ;you won’t worry about it here.Chapter 3 will go over branches and references in detail.
Let’s say you add n new file to your peoject, a simple README file .If the file didn’t exist before, and you run git status, you see your untracked file like so:
echo 'My Project' > README
git status
On branch master
Untracked files:
(use "git add <file>..."to include in what will be committed)
README
nothing added to commit but untracked files present (use "git add" to track)
You can see that your new README file is untracked ,because it’s under the “Untracked files” heading in your status output. Untracked basically means that Git sees a file you didn’t have in the previous snapshot (commit);Git won’t start including it in your commit snapshots until you explicitly tell it to do so. It does this so you don’t accidentally begin including generated binary files or other files that you did not mean to include. You do want to start inclduing README,so let’s start tracking the file.
Git 不会自动跟踪任何文件,除非你明确的告诉它要跟踪那些文件。这样你就不用担心Git会把二进制文件或者其他一下你不想进行跟踪的文件进行跟踪。
Tracking New Files
In order to begin tracking a new file, you use the command git add.To begin tracking the README file ,you can run this:
git add README
If you run your status command again,you can see that your README file is now tracked and staged to be committed:
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>...."to unstage)
new file: README
You can tell that it’s staged because it’s under the “Changes to be committed”heading. If you commit at this point, the version of the file at the time you ran git add is what will be in the historical snapshot.You may recall that when you ran git init earlier, you then ran git add (files)-that was to begin tracking files in your directory.The git add command takes a path name for either a file or a directory; if it’s a directory, the command adds all the files in that direcotry recursiverly.
文件在“Changes to be committed”下面,证明文件已经被存储了,如果你在这个时候提交,文件的版本将会存储在历史快照中。你还会从新调用git add当你调用了git init,接着调用了git add(开始跟踪目录下的文件);如果是目录的话,将会递归的跟踪所有文件。
Stagin Modified Files
Let’s change a file that was already tracked. If you change a previously tracked file called CONTRIBUTTING.md and then run your git status command again, you get something that looks like this:
git status
On branch master
Changes to be committed:
(use "git reset HEAD<file>.."to unstage)
new file: README
Changes not staged for commit:
(use "git add <file>..."to update what will be committed)
(use "git checkout -- <file>..." to discard chages in working directory)
modified: CONTRIBUTTING.md
The CONTRIBUTING.md file appears under a section named “Changes no staged for commit”-which means that a file that is tracked has been modified is the working directory but not yet staged. To stage it, you run the git add command. git add is a multipurpose command - you use it to begin tracking new files, to stage files, and to do other things like marking merge-conflicted files as resolved. It may be helpful to think of it more as “add this content to the next commit”rather than “add this file to the project”. Let’s run git add now to stage the CONTRIBUTING.md file, and then run git status again:
git add CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..."to unstage)
new file: README
modified: CONTRIBUTING.md
Both files are staged and will go into your next commit. At this point,suppose you remember one little change that you want to make in CONTRIBUTING.md before you commit it. You open it again and make that change, and you’re ready to commit. However, let’s run git status one more time:
vim CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..."to unstage)
new file: README
modified: CONTRIBUTING.md
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..."to discard chages in working directory)
modified: CONTRIBUTING.md
Whta the heck?Now CONTRIBUTING.md is listed as both staged and unstaged. How is that possible? It turns out that Git stages a file exactly as it is when you run the git add command. If you commit now, the version fo CONTRIBUTING.md as it was when you last ran git add command is how it will go into the commit, not the version of the file as it looks in your working directory when you run git commit .If you modify a file after you run git add, you have run git add again to stage the latest version of the file:
CONTRIBUTING.md有两种状态,已存储和未存储。这怎么可能?当你运行git add的时候Git的确存储了一个文件。如果你现在提交,CONTRIBUTING.md就是你最后一次运行git add的状态会被提交,而不是你当前文件的状态。如果你改变了一个文件,你就要在运行git add去存储最新的文件状态。
git add CONTRIBUTING.md
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..."to unstage)
new file: READ
modified: CONTRIBUTING.md
While the git status output is pretty comrehensive, it’s also quite wordy.Git also has a short status flag so you can see your changes in a more compack way. If you run git status -s or git status –short you get a far more simplified output from the command:
git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
New files that are’t tracked have ?? next to them, new file that hvae been added to the staging area have an A, modified files have an M and so on. There are two columns to the output -the left hand column indicates that the file is staged and the right hand column indicates that it’s modifeid. So for example in that output, the README file is modified in the working directory but not yet staged, while the lib/simplegit.rb file is modified and staged. The Rakefile was modified,staged and then modified again, so there are changes to it that are both staged and unstaged.
违背跟踪的文件前面是??已经被存储的文件有一个A,被改变的文件有一个M。但是M在左边,在右边,和两边都有,又不太相同。
例如:M在右边表示,改变了,但没有staged,在左边,改变了,并且已经staged,两边都有,改变了,staged,又改变了。
Ignoring Files
Often,you’ll have a class of files that you don’t want Git to automatically add or even show you as being 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 listing patterns to match them named .gitignore. Here is an example .gitignore file:
cat .gitignore
*.[oa]
*~
The first line tells Git to ignore any file end 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 fiels that end with a tilde(~),which is used by may text editors such as Emacs to mark temporary files. You may also include a log, tmp or pid directory; automatically generated documentation; and so on. Setting up a .gitignore file before you get going is generally a good idea so you don't accidentally commit files that you really don't want in your Git repository.
The rules for the patterns you can put in the .gitignore file are as follows:
- Bland lines or lines start with # are ignored.
- Standard glob patterns work
- You can start patterns with a forward slash (/) to avodi recursivity.
- You can end patterns with a forward slash (/) to specify a directory
- You can negate a pattern by starting it with an exclamation point(!).
Glob patterns are like simplified regular expressions that shells use.An aster-isk (*) matches aero or more characters;[abc] matches any character inside the brackets (int this case a,b,or c); a question mark(?) matches a single character; and brackets enclosing characters separated by a hyphen([0-9])matches any character between them (int this case 0 through 9).You can also use two asterisks to match nested directories; a/**/z would match a/z ,a/b/z,a/b/c/z, and so on.
Here is another example .gitignore file:
# no .a files
*.a
# but do track lib.a, even though you’re ignoring .a files above !lib.a
# only ignore the TODO file in the current directory, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
#ignore all .pdf files in the doc/ directory
doc/**/*.pdf
GitHub maintains a fairly comprehensive list of good .gitignore file examples for dozens of projects and languages at https://github.com/github/gitignore if you want a starting point for your project.
Viewing Your Staged and Unstaged Changes
If the git status command is too vague for you - you want to know exactly what you changed, not just which files were changed - you can use the git diff command . We’ll cover git diff in more detail later, but you’ll probably use it most often to answer these two questions: What have you chaged but not yet staged? And what have you staged that you are about to commit? although git status answers those questions very generally by listing the file names, git diff shows you the exact lines added and removed - the patch, as it were.
Let’s say you edit and stage the README file again and then edit the CONTRIBUTING.md file without staging it. If you run your git status command , you once again see something like this:
git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README
Changes not staged for commit:
(use "git add <file>... " to update what will be committed)
(use "git checkout -- <file>..." to discard chages in working directory)
modified: CONTRIBUTING.md
To see what you’ve chaged but not yet staged, type git diff with no other arguments:
git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
Please include a nice description of your changes when you submit your PR;
if we have to read the whole diff to figure out why you're contributing in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your chages into comprehensive chunks if your patch is
+longer than a dozen lines.
If you are starting to work on a particular area, feel free to submit a PR that highlights your work in progress (and note in the PR title that it's)
That command compares what is in your working directory with what is in your staging ared. The result tells you the changes you’ve made that you haven’t yet staged.
If you want to see what you’ve staged that will go into your next commit, you can use git diff – staged. This command compares your staged chages to your last commit:
git diff --staged
diff --git /a README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
++ b/README
@@ -0,0 =1 @@
+My Project
It’s important to note that git diff by iteself doesn’t show all chages mad since your last commit - only chages taht are still unstaged. This can be confusing, beacuse if you’ve staged all of your chages, git diff will give you no output,
For another example,if you stage the CONTRIBUTING.md file and then edit it, you can use git diff to see the canges in the file that are staged and the canges that are unstaged. I four environment look s like this: