文章目录
工作区与暂存区
工作区(Working directory):不仅包含你实际更改的文件,还应当包括当前修改但未add存入暂存区的文件变化信息。
暂存区(Stage或index):临时存储文件的变化信息。在git add file操作之后,暂存区中将记录file文件上的修改信息。暂存区的存在更细化了时间节点,要知道commit的往往是有重大改变的版本或者是在一次修改工作整体完成之后才使用commit。而在这之前需要保存的修改,自然需要一个缓存区暂时存放。
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。有最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD
HEAD
可以理解为一个游标 一直指向当前我们所在版本库的地址 就是我们当前所在版本库的头指针。当然 我们也可以不使用HEAD 可以直接使用版本库的地址 版本库地址 可以用 git log
命令打印出来。
如下图 v1.0 的版本库地址为 f0a1684
$ git log --online
65a7643 (HEAD -> master) v3.0
c8a7da4 v2.0
f0a1684 v1.0
各区架构图:
撤销操作主要有如下几种
$ git commit --amend #撤销上一次提交 并将暂存区文件重新提交
$ git checkout -- <file> #拉取暂存区文件 并将其替换成工作区文件
$ git reset HEAD -- <file> #拉取最近一次提交到版本库的文件到暂存区 不影响工作区
注:独立的--
可以消除file与branch的名称歧义。如果有个分支名称和你的file一样,不加独立的--
就会变成切换分支。
git checkout与git reset
$ git checkout -- <file>
撤销对工作区的修改。把file文件在工作区的修改全部撤销,这里有两种情况:
- readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态.
其实checkout是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
$ git reset HEAD -- <file>
git reset
命令既可以回退版本,又能把暂存区的修改撤销(unstage),重新放回工作区。这个命令仅改变暂存区,并不改变工作区。
这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何改变。
而运行之后,暂存区变干净,相当于工作区相对暂存区有新的修改,可以使用git checkout
命令丢弃工作区该修改。
假设你不但改错了东西,还从暂存区提交到了本地版本库,怎么办呢?版本回退讲了可以回退到上一个版本。不过,这是有条件的,就是你还没有把本地版本库推送到远程。
git rm 与 git reset
git rm
:用于删除文件
git reset
:用于将当前HEAD复位到指定状态。一般用于撤消之前的一些操作(如:git add,git commit等)。
git rm <file_path>
删除暂存区和版本库分支上的文件,同时工作区也不需要
git rm --cached <file_path>
删除暂存区或版本库分支上的文件, 但工作区需要使用, 只是不希望被版本控制(适用于已经被git add,但是又想撤销的情况)
git reset HEAD -- file
回退暂存区里的文件
注:先手动删除工作区文件再git rm <file>
等效git add <file>
撤销
撤销push
- 查看日志,获取需要回退的版本号
git log
- 重置至指定版本的提交,达到撤销提交的目的
然后执行 git log 查看# git reset --soft 不删除工作空间改动代码,撤销commit,不撤销add git reset --soft 4f5e9a90edeadcc45d85f43bd861a837fa7ce4c7
- 强制提交当前版本号
至此,撤销push提交完成。git push origin ${branch} --force
注:
两种命令: git reset –-soft 与 git reset –-hard
区别:前者只是改变了HEAD的指向,本地代码不会变化,我们使用git status依然可以看到,同时也可以git commit提交。后者直接会改变本地源码,不仅仅指向变化了,代码也回到了那个版本时的代码
撤销add
- Git中
HEAD
代表当前版本,上一个版本就是HEAD^
,再上一个版本就是HEAD^^
依次类推 HEAD~2
2个版本
# 已经add了的话,那么checkout是没任何作用的,因为checkout是用版本库里的版本替换工作区的版本不影响暂存区,而add后工作区的修改已进入暂存区,所以要先取消添加才可以撤回提交
# 使用reset默认的--fixed参数,假装回退到当前版本,撤销add
git reset HEAD # 后面什么都不跟的话 就是上一次add里面的全部撤销了
# 撤销指定文件的add
git reset HEAD src/com/jay/example/testforgit/MainActivity.java
# reset 有三个参数
--fixed # 默认,不删除工作空间改动代码,撤销commit,撤销add
--soft # 不删除工作空间改动代码,撤销commit,不撤销add
--hard # 删除工作空间改动代码,撤销commit,不撤销add
#工作区回到与版本库一致
git checkout -- src/com/jay/example/testforgit/MainActivity.java
撤销commit
-
查看需要撤销的commit的前面一个提交版本的id:
git log
-
重置至指定版本的提交,达到撤销提交的目的
git reset --hard ${id}
该${id}替换为需要撤销的commit的提交的前面一个提交的版本,即需要恢复到的提交的id。
或$ git reset HEAD^ $ git reset HEAD~ $ git reset HEAD~2 # 回退2个版本 # 注意在windows的终端使用该命令时,由于^为windows的默认换行符 # windows下 $ git reset "HEAD^" $ git reset HEAD^^
-
执行 git log 查看,commit提交已撤销
回退到remote
git revert:撤销某个版本的提交
git log
git reset --hard HEAD
或者
git reset --hard ad2080c
# 撤销<commit-hash>这个版本的操作
git revert [-n] <commit-hash>
# 默认需要立刻commit,可以添加-n或--no-commit参数推迟commit
# 接下来直接commit、push即可,会在log中追加新的commit记录
# 连续多个revert
git revert -n <commit-hash_start>..<commit-hash_end>
# 会撤销( commit-hash_start, commit-hash_end ] 的提交
# 若要撤销执行完的revert操作,只需对这个revert操作也执行一次revert即可
git reset + git push -f
# 回退到<commit-hash>这个版本
git reset <commit-hash>
# 强制推送
git push -f
# 注意,此种回退相当于彻底回退到之前的版本,晚于该版本的提交log也会被清除,且此次回退无记录
回退后再回新版本
# 查看输入过的指令找到版本号
$ git reflog
# 键入
$ git reset --hard ad2080c
删除提交到本地仓的文件,不影响本地和远程
法一:删除本地仓的大文件
有时候误操作了大文件,推送到本地仓库却无法提交到远程仓库(报错)
$ dir #查看本地仓的大文件
$ git rm -r --cached <file>/<dir> # 删除文件或文件夹,名称如果有空格则需要用"\ "来拼接,如:python python要换成python\ python
或
根据提示执行命令,如下查看大文件是哪个,直接删除这个大文件
从commit的提交历史中删除指定文件
$ git filter-branch --tree-filter 'rm -f <file>' HEAD
删除后再次push提交。
法二:重拉本地仓库
从云端重新克隆一个仓库,把修改好的本地文件放入新的git本地仓库,旧的删除
常用命令
- 本地仓库常用操作
$ git add <file> # 将工作文件修改提交到本地暂存区 $ git add . # 将所有修改过的工作文件提交暂存区 $ git commit -m "Commit Message" # 提交修改(即把缓存区的内容提交到版本库中) $ git reset --hard # 恢复最近一次提交过的状态,即放弃上次提交后的所有本次修改 $ git revert <$id> # 恢复某次提交的状态,恢复动作本身也创建次提交对象 $ git revert HEAD # 恢复最后一次提交的状态 $ git log <file> # 查看该文件每次提交记录 $ git br <new_branch> # 创建新的分支 $ git br -v # 查看各个分支最后提交信息 $ git co <branch> # 切换到某个分支 $ git co -b <new_branch> # 创建新的分支,并且切换过去
- 远程仓库常用命令
$ git push origin master # 将本地主分支推到远程主分支, origin是远程仓库名 $ git pull origin master # 抓取远程仓库分支更新并合并到本地 $ git remote -v # 查看远程服务器地址和仓库名称 $ git remote show origin # 查看远程服务器仓库状态 $ git remote add origin git@github:robbin/robbin_site.git # 添加远程仓库地址