diff
$ git diff #比较工作区和缓存区的不同
$ git diff --cached #比较缓存区和 HEAD 不同
$ git diff HEAD #比较工作区和 HEAD 不同,就里的 HEAD 也可换成任意版本号
例
比较工作区和缓存区的不同:
比较缓存区和 HEAD 不同:
比较工作区和 HEAD 不同,就里的 HEAD 也可换成任意版本号:
checkout
checkout大体上分成两种情况
- git checkout [branch|<commit>|head]。这种是 checkout 整个版本或切换分支。
- git checkout commit|head file。将某个版本下的信息将覆盖暂存区和工作区。
- git checkout file。将暂存区将会覆盖工作区。
1、git checkout [<commit>|head]
git checkout [<commit>|head] :将HEAD移到一个新的分支,然后更新工作目录。因为这可能会覆盖本地的修改,Git强制你提交所有的更改,这与reset是不同的,这种方式就可以有效避免了工作区和暂存区的文件处理问题。reset版本回退会丢失一前的版本。而checkout不会,只是就head指向的位置移动了,我们还是可以移回来。
[hongshicheng@22:21:28]~/learnGit$ git log --oneline --graph --all
* a8cc7d9 (HEAD -> testing) add b.txt
| * 4305959 (master) add a3
| * 2a06c56 add a2
|/
* 89b3021 add a1
* a58d8ce init
[hongshicheng@22:21:32]~/learnGit$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
[hongshicheng@22:22:17]~/learnGit$ git log --oneline --graph --all
* a8cc7d9 (testing) add b.txt
| * 4305959 (HEAD -> master) add a3
| * 2a06c56 add a2
|/
* 89b3021 add a1
* a58d8ce init
[hongshicheng@22:22:31]~/learnGit$ git checkout 2a06c56
Note: checking out '2a06c56'.
You are in 'detached HEAD' state.
HEAD is now at 2a06c56... add a2
[hongshicheng@22:22:47]~/learnGit$ git log --oneline --graph --all
* a8cc7d9 (testing) add b.txt
| * 4305959 (master) add a3
| * 2a06c56 (HEAD) add a2
|/
* 89b3021 add a1
* a58d8ce init
[hongshicheng@22:22:49]~/learnGit$ git checkout a8cc7d9
Previous HEAD position was 2a06c56... add a2
HEAD is now at a8cc7d9... add b.txt
[hongshicheng@22:23:06]~/learnGit$ git log --oneline --graph --all
* a8cc7d9 (HEAD, testing) add b.txt
| * 4305959 (master) add a3
| * 2a06c56 add a2
|/
* 89b3021 add a1
* a58d8ce init
[hongshicheng@22:23:09]~/learnGit$ git checkout testing
Switched to branch 'testing'
[hongshicheng@22:23:24]~/learnGit$ git log --oneline --graph --all
* a8cc7d9 (HEAD -> testing) add b.txt
| * 4305959 (master) add a3
| * 2a06c56 add a2
|/
* 89b3021 add a1
* a58d8ce init
[hongshicheng@22:23:27]~/learnGit$
2、加文件名参数
不会移动HEAD引用, 将某个版本下的信息复制到工作区和暂存区。
[hongshicheng@21:17:43]~/learnGit$ ls
a.txt
[hongshicheng@21:17:56]~/learnGit$ cat a.txt
a1
a2
a3
[hongshicheng@21:18:00]~/learnGit$ git log --oneline
4305959 (HEAD -> master) add a3
2a06c56 add a2
89b3021 add a1
a58d8ce init
[hongshicheng@21:18:15]~/learnGit$
[hongshicheng@21:18:15]~/learnGit$ echo 'a4' >> a.txt
[hongshicheng@21:19:33]~/learnGit$ git add a.txt
[hongshicheng@21:19:43]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
[hongshicheng@21:20:04]~/learnGit$ git reset a.txt
Unstaged changes after reset:
M a.txt
[hongshicheng@21:20:40]~/learnGit$ git status a.txt
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
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: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
[hongshicheng@21:20:54]~/learnGit$
[hongshicheng@21:21:43]~/learnGit$ git checkout a.txt
[hongshicheng@21:21:54]~/learnGit$
[hongshicheng@21:21:55]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
[hongshicheng@21:21:58]~/learnGit$
[hongshicheng@21:22:01]~/learnGit$ git reset 2a06c56 a.txt
Unstaged changes after reset:
M a.txt
[hongshicheng@21:22:35]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
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: a.txt
[hongshicheng@21:22:43]~/learnGit$ git checkout a.txt
[hongshicheng@21:23:31]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
[hongshicheng@21:23:40]~/learnGit$ cat a.txt
a1
a2
[hongshicheng@21:23:49]~/learnGit$
2、git checkout commit|head file
将某个版本下的信息复制到工作区和暂存区。
[hongshicheng@21:44:43]~/learnGit$ git log --oneline
4305959 (HEAD -> master) add a3
2a06c56 add a2
89b3021 add a1
a58d8ce init
[hongshicheng@21:46:20]~/learnGit$
[hongshicheng@21:46:31]~/learnGit$ cat a.txt
a1
a2
a3
[hongshicheng@21:46:38]~/learnGit$
[hongshicheng@21:46:39]~/learnGit$ git checkout 2a06c56 a.txt
[hongshicheng@21:46:55]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
[hongshicheng@21:47:00]~/learnGit$ cat a.txt
a1
a2
[hongshicheng@21:47:54]~/learnGit$
[hongshicheng@21:49:12]~/learnGit$ git checkout HEAD a.txt
[hongshicheng@21:49:40]~/learnGit$
[hongshicheng@21:49:42]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
[hongshicheng@21:49:45]~/learnGit$
[hongshicheng@21:49:45]~/learnGit$ cat a.txt
a1
a2
a3
[hongshicheng@21:57:03]~/learnGit$
3、git checkout file。
不会移动HEAD引用,将暂存区将会覆盖工作区。 git checkout . "."是通配符表示所有文件。
[hongshicheng@22:05:19]~/learnGit$ cat a.txt
a3
[hongshicheng@22:05:35]~/learnGit$ echo 'a4' >> a.txt
[hongshicheng@22:05:45]~/learnGit$ git add .
[hongshicheng@22:06:01]~/learnGit$ cat a.txt
a3
a4
[hongshicheng@22:06:27]~/learnGit$ echo 'a5' >> a.txt
[hongshicheng@22:06:01]~/learnGit$ cat a.txt
a3
a4
a5
[hongshicheng@22:06:40]~/learnGit$ git status
On branch master
Your branch is ahead of 'origin1/master' by 5 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: a.txt
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: a.txt
[hongshicheng@22:07:04]~/learnGit$
[hongshicheng@22:07:09]~/learnGit$ git checkout a.txt
[hongshicheng@22:07:19]~/learnGit$
[hongshicheng@22:07:20]~/learnGit$ cat a.txt
a3
a4
[hongshicheng@22:07:27]~/learnGit$
一、reset
1、不加文件名参数
git reset [--hard|soft|mixed|merge|keep] [<commit> | HEAD] :将当前的分支重设(reset)到指定的<commit>或者HEAD(默认,如果不显示指定commit,默认是HEAD,即最新的一次提交)。我们可能reset到任何一个版本, 这样就会出现一个问题:暂存区待提交的文件如何处理,工作区还没有add的文件如何处理。
这时可以通过--soft、mixed、--hard来指定如何处理。–mixed是默认参数,也就是说执行reset的时候不给就认为是--mixed。
--soft :保留暂存区和工作区。
--mixed :重置暂存区(暂存区的所有内容都会丢失);保留工作区。
--hard :重置暂存区和工作区。
target代表想要将git指向到哪个commit
2、加文件名参数
如果带上文件参数,那么效果会是怎样的?
1、HEAD不会动
2、将那个commit的snapshot里的那个文件放到Index区域中 只有index区域中的内容发生改变
需要注意的是带文件参数的git reset没有--hard, --soft这两个参数。只有--mixed参数。
git reset [--mixed] [<commit> | HEAD] filename
恢复到历史版本
下面这个命令就是将某个文件恢复到历史版本上。
git reset eb43bf file.txt
eb43bf 为版本号
三、revert
上图可以看到git reset是会修改版本历史的,他会丢弃掉一些版本历史。
而git revert是根据那个commit逆向生成一个新的commit,版本历史是不会被破坏的。
已经push到远程仓库的commit不允许reset
上面已经讲了,git reset是会丢弃掉commit的。
如果commit已经被push到远程仓库上了,也就意味着其他开发人员就可能基于这个commit形成了新的commit,这时你去reset,就会造成其他开发人员的提交历史莫名其妙的丢失,或者其他灾难性的后果。
因此,一旦commit已经被push到远程仓库,那么是坚决不允许去reset它的。
rm
从工作区或暂存区中删除文件
git rm与git rm --cached
git rm [-f] file 同时删除暂存区和
工作区,如果文件有修改未提交的记录,可以使用-f 参数。等价于: rm -rf file ; git add file
git rm --cached file 只删除暂存区、保留
工作区
实例:
git rm [-f] file:
git rm --cached file :
由于缓存区文件被删除,工作区和缓存区对比表现为新增文件,缓存区和 head区对比表现为删除文件。
branch
git branch
命令不仅仅能创建和删除分支,如果不加任何参数,它会给出当前所有分支的清单:
$ git branch
iss53
* master
testing
注意看 master
分支前的 *
字符:它表示当前所在的分支。也就是说,如果现在提交更新,master
分支将随着开发进度前移。若要查看各个分支最后一个提交对象的信息,运行 git branch -v
:
$ git branch -v
iss53 93b412c fix javascript issue
* master 7a98805 Merge branch 'iss53'
testing 782fd34 add scott to the author list in the readmes
要从该清单中筛选出你已经(或尚未)与当前分支合并的分支,可以用 --merged
和 --no-merged
选项(Git 1.5.6 以上版本)。比如用 git branch --merged
查看哪些分支已被并入当前分支(译注:也就是说哪些分支是当前分支的直接上游。):
$ git branch --merged
iss53
* master
之前我们已经合并了 iss53
,所以在这里会看到它。一般来说,列表中没有 *
的分支通常都可以用 git branch -d
来删掉。原因很简单,既然已经把它们所包含的工作整合到了其他分支,删掉也不会损失什么。
另外可以用 git branch --no-merged
查看尚未合并的工作:
$ git branch --no-merged
testing
它会显示还未合并进来的分支。由于这些分支中还包含着尚未合并进来的工作成果,所以简单地用 git branch -d
删除该分支会提示错误,因为那样做会丢失数据:
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.
不过,如果你确实想要删除该分支上的改动,可以用大写的删除选项 -D
强制执行,就像上面提示信息中给出的那样。