Now we have a git repository for a real project, and we have extracted the working copies of all the files from this repository. Next, make some modifications to these files. After completing the objectives of a stage, submit this update to the repository.
Remember that all files in the working directory are in either of these statuses: tracked or not tracked. Tracked files are files that have been incorporated into version control management. They are recorded in the previous snapshot. After a period of time, their statuses may not be updated, modified or placed in the temporary storage area. All other files are not tracked. They neither have snapshots of the last update nor are in the current temporary storage area. When cloning a repository for the first time, all files in the working directory belong to the tracked file and the status is not modified.
After editing some files, git marks these files as modified. We gradually put these modified files in the temporary storage area, and wait until all the files in the temporary storage area are submitted at one time. So the file state change cycle 2-1 when git is used is shown.
Figure 2-1. File state change cycle
Check the current file status
To determine which files are in the current status, run the git status Command. If you execute this command immediately after cloning the repository, you will see an output similar to this:
$ git status# On branch masternothing to commit (working directory clean)
This shows that your current working directory is quite clean. In other words, there are no tracked files, and no files have been changed since the last submission. In addition, the above information also indicates that no new files are available in the current directory, otherwise git will list them here. Finally, the command also shows that the current branch is the master, which is the default branch name and can be modified. In the next chapter, we will discuss the branches and references in detail.
Now let's use Vim to edit a new file README, save and exit, and rungit status
The file is displayed in the list of untracked files:
$ vim README$ git status# On branch master# Untracked files:# (use "git add <file>..." to include in what will be committed)##READMEnothing added to commit but untracked files present (use "git add" to track)
It is under the "untracked Files" line. Git does not automatically include it in the tracking scope, unless you explicitly tell it to do so, so you don't have to worry about putting temporary files or anything into version management. But now we do want to track and manage the README file.
Tracking new files
Use commandsgit add
Start tracking a new file. Therefore, to track the README file, run:
$ git add README
Run againgit status
Command to view the README file that has been tracked and saved:
$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README#
As long as it is under the "changes to be committed" line, it indicates that it is saved. If the file is submitted at this time, the current version of the file will be kept in the history. You may think that we usedgit init
Then it runs.git add
Command to start tracking files in the current directory. The path of the file or directory to be tracked after git add. If it is a directory, it indicates recursively tracking all the files in the directory.
Save modified files
Now we can modify the files that have been tracked before.benchmarks.rb
And then run againstatus
Command to view the status report:
$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README## Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: benchmarks.rb#
The file benchmarks. RB appears under the "changed but not updated" line, indicating that the content of the tracked file has changed, but it has not been placed in the temporary storage area. To save this update temporarily, you need to rungit add
Command (this is a multi-function command. Depending on the status of the target file, this command has different effects: You can use it to start tracking new files, or put tracked files in the temporary storage area, it can also be used to mark conflicting files as resolved during merge ). Now let's rungit add
Put benchmarks. Rb in the temporary storage area and check again.git status
Output:
$ git add benchmarks.rb$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README#modified: benchmarks.rb#
Now both files have been saved, and will be recorded in the warehouse at the next submission. Suppose that you want to add a comment in benchmarks. RB, re-edit the disk, and submit it. But it's not slow. Run it again.git status
Let's see:
$ vim benchmarks.rb $ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README#modified: benchmarks.rb## Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: benchmarks.rb#
Hell! The benchmarks. RB file appears twice! How can this problem be solved if one calculation is not saved? In fact, git only saves the version you used to run the GIT add command. If you submit the version now, you will submit the version before adding the comment, instead of the version in the current working directory. So, rungit add
The revised document needs to be re-run.git add
Save the latest version again:
$ git add benchmarks.rb$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README#modified: benchmarks.rb#
Ignore some files
In general, some files do not need to be managed by git, and we do not want them to appear in the list of untracked files. Generally, these files are automatically generated, such as logs or files created during compilation. We can create a file named. gitignore to list the file mode to be ignored. Here is a simple example:
$ cat .gitignore*.[oa]*~
The first line tells git to ignore all files ending with. O or.. Generally, such object files and archive files are generated during compilation, so we do not need to track their versions. The second line tells git to ignore all (~
). Many text editing software (such as Emacs) use this file name to save copies. In addition, you may need to ignore the log, TMP or PID directory, and automatically generated documents. You need to develop the habit of setting up. gitignore files from the beginning, so as not to mistakenly submit such useless files in the future.
The format of file. gitignore is as follows:
- All blank lines or lines starting with '#' are ignored by git.
- You can use the standard glob pattern matching. * The final matching mode is followed by a backslash (
/
) Indicates the directory to be ignored. * To ignore files or directories other than the specified mode, you can add an exclamation point (!
.
The so-called glob mode refers to the simplified regular expression used by shell. Asterisk (*
) Matches zero or multiple arbitrary characters;[abc]
Match any character in square brackets (this example matches either A or B or C); Question mark (?
) Matches only one arbitrary character. If two characters are separated by a short line in square brackets, it means that all the characters within the two character ranges can match (for example[0-9]
Matches all numbers 0 to 9 ).
Let's look at an example of the. gitignore file:
# This is a comment-it will be ignored by git *. A # All files ending with. A will be ignored! Lib. A # But Lib. except for a/todo # ignore only the todo files under the project root directory, excluding subdir/todobuild/# ignore all files under the build/directory DOC /*. TXT # DOC/notes.txt is ignored, but Doc/Server/arch.txt is not included.
View saved and unsaved updates
Actuallygit status
The display is relatively simple. It only lists the modified files. To view the modified files, you can usegit diff
Command. We will introduce it in detail later.git diff
But now it can answer our two questions: which updates have not been saved yet? What updates have been saved and ready for submission next time?git diff
The added and deleted rows are displayed in the format of the file patch.
If you modify the README file and save it for temporary storage, do not save it after editing the benchmarks. RB file. Runstatus
Command, you will see:
$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)##new file: README## Changed but not updated:# (use "git add <file>..." to update what will be committed)##modified: benchmarks.rb#
To view the updates of files that have not been saved, enter the parameters without adding them.git diff
:
$ git diffdiff --git a/benchmarks.rb b/benchmarks.rbindex 3cb747f..da65585 100644--- a/benchmarks.rb+++ b/benchmarks.rb@@ -36,6 +36,10 @@ def main @commit.parents[0].parents[0].parents[0] end+ run_code(x, 'commits 1') do+ git.commits.size+ end+ run_code(x, 'commits 2') do log = git.commits('master', 15) log.size
This command compares the differences between the current file in the working directory and the snapshots in the temporary storage area, that is, the changed content has not been saved.
You can usegit diff --cached
Command. (GIT 1.6.1 and later versions are also allowedgit diff --staged
, The effect is the same, but it is easier to remember .) To see the actual results:
$ git diff --cacheddiff --git a/README b/READMEnew file mode 100644index 0000000..03902a1--- /dev/null+++ b/README2@@ -0,0 +1,5 @@+grit+ by Tom Preston-Werner, Chris Wanstrath+ http://github.com/mojombo/grit++Grit is a Ruby library for extracting information from a Git repository
Note thatgit diff
But it shows that there are no temporary changes, rather than the difference between this job and the last commit. So sometimes you save all the updated files and rungit diff
There is nothing behind it, that's why.
As mentioned earlier, save the temporary benchmarks. Rb and then edit it and run it.git status
The two versions before and after the temporary storage are displayed:
$ git add benchmarks.rb$ echo '# test line' >> benchmarks.rb$ git status# On branch master## Changes to be committed:##modified: benchmarks.rb## Changed but not updated:##modified: benchmarks.rb#
Run nowgit diff
Check the changes before and after temporary storage:
$ git diff diff --git a/benchmarks.rb b/benchmarks.rbindex e445e28..86b2f7c 100644--- a/benchmarks.rb+++ b/benchmarks.rb@@ -127,3 +127,4 @@ end main() ##pp Grit::GitRuby.cache_client.stats +# test lineand git diff --cached to see what you’ve staged so far:$ git diff --cacheddiff --git a/benchmarks.rb b/benchmarks.rbindex 3cb747f..e445e28 100644--- a/benchmarks.rb+++ b/benchmarks.rb@@ -36,6 +36,10 @@ def main @commit.parents[0].parents[0].parents[0] end+ run_code(x, 'commits 1') do+ git.commits.size+ end+ run_code(x, 'commits 2') do log = git.commits('master', 15) log.size
Submit update
The current temporary storage area is ready for submission. Before that, be sure to confirm whether there are any modified or newly created filesgit add
Otherwise, the changes that have not been saved will not be recorded during submission. Therefore, usegit status
Check whether all of them have been saved, and then run the submit command.git commit
:
$ git commit
In this way, the text editor is started to enter the description of this submission. (By default, the software specified by the Shell environment variable $ editor is enabled, which is usually vim or Emacs. You can also usegit config --global core.editor
Command to set your favorite editing software .)
The editor displays text similar to the following (in this example, the screen display mode of VIM is used ):
# Please enter the commit message for your changes. Lines starting# with '#' will be ignored, and an empty message aborts the commit.# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## new file: README# modified: benchmarks.rb ~~~".git/COMMIT_EDITMSG" 10L, 283C
We can see that the default submitted message contains the last rungit status
The output is placed in the comment line, and there is an empty line at the beginning for you to input and submit the description. You can remove these comment lines, but it doesn't matter if you keep them. It can help you think back to the updated content. (If you think this is not enough, you can use-v
Option .) When you exit the editor, git will discard the comment line and submit the description content and this update to the repository.
You can also use the-M parameter followed by instructions to submit updates in a single command line:
$ git commit -m "Story 182: Fix benchmarks for speed"[master]: created 463dc4f: "Fix benchmarks for speed" 2 files changed, 3 insertions(+), 0 deletions(-) create mode 100644 README
Okay, now you have created the first commit! As you can see, after the submission, it will tell you which branch (master) is currently submitted, and what is the complete SHA-1 checksum for this submission (463dc4f
.
Remember, when you submit a snapshot, it is recorded as a snapshot in the temporary storage area. Any snapshot that has not been saved is still in the modified status. You can include the snapshot in version management when you submit the snapshot next time. Each time you submit an operation, a snapshot is taken for your project. You can return to this status or compare it later.
Skip Using temporary area
Although you can carefully prepare the details to be submitted by using the temporary storage area, it is sometimes cumbersome to do so. Git provides a way to skip the use of temporary regions, as long asgit commit
Add-a
Option, git will automatically save all the files that have been tracked and submit them together, thus skippinggit add
Steps:
$ git status# On branch master## Changed but not updated:##modified: benchmarks.rb#$ git commit -a -m 'added new benchmarks'[master 83e38c7] added new benchmarks 1 files changed, 5 insertions(+), 0 deletions(-)
Have you seen it? No longer required before submissiongit add
File benchmarks. RB.
Remove a file
To remove a file from git, you must remove it from the list of Tracked files (specifically, from the staging area) and then submit the file. Availablegit rm
Command to complete this task, and then delete the specified file from the working directory, so that it will not appear in the list of untracked files.
If you just manually delete the file from the working directory, rungit status
In the "changed but not updated" section (that is, _ not saved _ list), you will see:
$ rm grit.gemspec$ git status# On branch master## Changed but not updated:# (use "git add/rm <file>..." to update what will be committed)## deleted: grit.gemspec#
Then rungit rm
Record the object removal operation:
$ git rm grit.gemspecrm 'grit.gemspec'$ git status# On branch master## Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## deleted: grit.gemspec#
At the end of the submission, the file is no longer included in version management. You must use the force delete option to delete a file that has been modified and put in the temporary storage area.-f
The first letter of force to prevent loss of modified content after the file is deleted by mistake.
In another case, we want to delete the file from the GIT repository (that is, remove from the staging area), but still want to keep it in the current working directory. In other words, only the trail list is deleted. For example, some large log files or a pile.a
After the file is compiled and accidentally included in the repository, you need to remove the trace but not delete the file so that you can.gitignore
File,--cached
Option:
$ git rm --cached readme.txt
The names of files or directories can be listed later, or the glob mode can be used. For example:
$ git rm log//*.log
Notice Asterisk*
Previous backslash/
Because git has its own file mode extension matching method, we don't need shell to help expand it, only delete files in the specified directory without recursive matching. The preceding example specifies the directory, so the effect is equivalent. However, the following example uses recursive matching, so a backslash must be added .). This command deletes alllog/
The directory extension is.log
. For example:
$ git rm /*~
Recursively deletes all~
.
Move files
Unlike other VCs, git does not track file movement operations. If a file is renamed in git, the metadata stored in the repository does not show that this is a renaming operation. However, git is very clever, and it will deduce what happened. As for how it is done, let's talk about it later.
In this case, when you see git'smv
The command must be confusing. To rename a file in git, you can do this:
$ git mv file_from file_to
It will work as expected. In fact, even if you view the status information at this time, you can see the RENAME operation instructions clearly:
$ git mv README.txt README$ git status# On branch master# Your branch is ahead of 'origin/master' by 1 commit.## Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## renamed: README.txt -> README#
In fact, rungit mv
It is equivalent to running the following three commands:
$ mv README.txt README$ git rm README.txt$ git add README
In this separate operation, git will realize that this is a renaming, so no matter what method it is. Of course, usegit mv
It is much lighter, but sometimes you need to delete the old file name and add a new file name before submitting it in batches with other tools.