git初阶

Git常用命令及方法大全

下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库
本地分支关联远程:git branch --set-upstream-to=origin/beta beta

一、新建代码库


     
       
       
       
       
  1. # 在当前目录新建一个Git代码库
  2. $ git init
  3. # 新建一个目录,将其初始化为Git代码库
  4. $ git init [project -name ]
  5. # 下载一个项目和它的整个代码历史
  6. $ git clone [url ]

二、配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。


     
       
       
       
       
  1. # 显示当前的Git配置
  2. $ git config --list
  3. # 编辑Git配置文件
  4. $ git config -e [ --global ]
  5. # 设置提交代码时的用户信息
  6. $ git config [ --global ] user .name "[name]"
  7. $ git config [ --global ] user .email "[email address]"

三、增加/删除文件


     
       
       
       
       
  1. # 添加指定文件到暂存区
  2. $ git add [file1 ] [file2 ] . . .
  3. # 添加指定目录到暂存区,包括子目录
  4. $ git add [dir ]
  5. # 添加当前目录的所有文件到暂存区
  6. $ git add .
  7. # 添加每个变化前,都会要求确认
  8. # 对于同一个文件的多处变化,可以实现分次提交
  9. $ git add -p
  10. # 删除工作区文件,并且将这次删除放入暂存区
  11. $ git rm [file1 ] [file2 ] . . .
  12. # 停止追踪指定文件,但该文件会保留在工作区
  13. $ git rm --cached [file ]
  14. # 改名文件,并且将这个改名放入暂存区
  15. $ git mv [file -original ] [file -renamed ]

四、代码提交


     
       
       
       
       
  1. # 提交暂存区到仓库区
  2. $ git commit -m [message ]
  3. # 提交暂存区的指定文件到仓库区
  4. $ git commit [file1 ] [file2 ] . . . -m [message ]
  5. # 提交工作区自上次commit之后的变化,直接到仓库区
  6. $ git commit -a
  7. # 提交时显示所有diff信息
  8. $ git commit -v
  9. # 使用一次新的commit,替代上一次提交
  10. # 如果代码没有任何新变化,则用来改写上一次commit的提交信息
  11. $ git commit --amend -m [message ]
  12. # 重做上一次commit,并包括指定文件的新变化
  13. $ git commit --amend [file1 ] [file2 ] . . .

五、分支


     
       
       
       
       
  1. # 列出所有本地分支
  2. $ git branch
  3. # 列出所有远程分支
  4. $ git branch -r
  5. # 列出所有本地分支和远程分支
  6. $ git branch -a
  7. # 新建一个分支,但依然停留在当前分支
  8. $ git branch [branch -name ]
  9. # 新建一个分支,并切换到该分支
  10. $ git checkout -b [branch ]
  11. # 新建一个分支,指向指定commit
  12. $ git branch [branch ] [commit ]
  13. # 新建一个分支,与指定的远程分支建立追踪关系
  14. $ git branch --track [branch ] [remote -branch ]
  15. # 切换到指定分支,并更新工作区
  16. $ git checkout [branch -name ]
  17. # 切换到上一个分支
  18. $ git checkout -
  19. # 建立追踪关系,在现有分支与指定的远程分支之间
  20. $ git branch -- set -upstream [branch ] [remote -branch ]
  21. # 合并指定分支到当前分支
  22. $ git merge [branch ]
  23. # 选择一个commit,合并进当前分支
  24. $ git cherry -pick [commit ]
  25. # 删除分支
  26. $ git branch -d [branch -name ]
  27. # 删除远程分支
  28. $ git push origin --delete [branch -name ]
  29. $ git branch -dr [remote /branch ]

六、标签


     
       
       
       
       
  1. # 列出所有tag
  2. $ git tag
  3. # 新建一个tag在当前commit
  4. $ git tag [tag ]
  5. # 新建一个tag在指定commit
  6. $ git tag [tag ] [commit ]
  7. # 删除本地tag
  8. $ git tag -d [tag ]
  9. # 删除远程tag
  10. $ git push origin :refs /tags / [tagName ]
  11. # 查看tag信息
  12. $ git show [tag ]
  13. # 提交指定tag
  14. $ git push [remote ] [tag ]
  15. # 提交所有tag
  16. $ git push [remote ] --tags
  17. # 新建一个分支,指向某个tag
  18. $ git checkout -b [branch ] [tag ]

七、查看信息


     
       
       
       
       
  1. # 显示有变更的文件
  2. $ git status
  3. # 显示当前分支的版本历史
  4. $ git log
  5. # 显示commit历史,以及每次commit发生变更的文件
  6. $ git log -- stat
  7. # 搜索提交历史,根据关键词
  8. $ git log -S [keyword ]
  9. # 显示某个commit之后的所有变动,每个commit占据一行
  10. $ git log [tag ] HEAD --pretty =format : %s
  11. # 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
  12. $ git log [tag ] HEAD --grep feature
  13. # 显示某个文件的版本历史,包括文件改名
  14. $ git log --follow [file ]
  15. $ git whatchanged [file ]
  16. # 显示指定文件相关的每一次diff
  17. $ git log -p [file ]
  18. # 显示过去5次提交
  19. $ git log - 5 --pretty --oneline
  20. # 显示所有提交过的用户,按提交次数排序
  21. $ git shortlog -sn
  22. # 显示指定文件是什么人在什么时间修改过
  23. $ git blame [file ]
  24. # 显示暂存区和工作区的差异
  25. $ git diff
  26. # 显示暂存区和上一个commit的差异
  27. $ git diff --cached [file ]
  28. # 显示工作区与当前分支最新commit之间的差异
  29. $ git diff HEAD
  30. # 显示两次提交之间的差异
  31. $ git diff [first -branch ] . . . [second -branch ]
  32. # 显示今天你写了多少行代码
  33. $ git diff --shortstat "@{0 day ago}"
  34. # 显示某次提交的元数据和内容变化
  35. $ git show [commit ]
  36. # 显示某次提交发生变化的文件
  37. $ git show --name -only [commit ]
  38. # 显示某次提交时,某个文件的内容
  39. $ git show [commit ] : [filename ]
  40. # 显示当前分支的最近几次提交
  41. $ git reflog

八、远程同步


     
       
       
       
       
  1. # 下载远程仓库的所有变动
  2. $ git fetch [remote ]
  3. # 显示所有远程仓库
  4. $ git remote -v
  5. # 显示某个远程仓库的信息
  6. $ git remote show [remote ]
  7. # 增加一个新的远程仓库,并命名
  8. $ git remote add [shortname ] [url ]
  9. # 取回远程仓库的变化,并与本地分支合并
  10. $ git pull [remote ] [branch ]
  11. # 上传本地指定分支到远程仓库
  12. $ git push [remote ] [branch ]
  13. # 强行推送当前分支到远程仓库,即使有冲突
  14. $ git push [remote ] --force
  15. # 推送所有分支到远程仓库
  16. $ git push [remote ] --all

九、撤销


     
       
       
       
       
  1. # 恢复暂存区的指定文件到工作区
  2. $ git checkout [file ]
  3. # 恢复某个commit的指定文件到暂存区和工作区
  4. $ git checkout [commit ] [file ]
  5. # 恢复暂存区的所有文件到工作区
  6. $ git checkout .
  7. # 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
  8. $ git reset [file ]
  9. # 重置暂存区与工作区,与上一次commit保持一致
  10. $ git reset --hard
  11. # 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
  12. $ git reset [commit ]
  13. # 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
  14. $ git reset --hard [commit ]
  15. # 重置当前HEAD为指定commit,但保持暂存区和工作区不变
  16. $ git reset --keep [commit ]
  17. # 新建一个commit,用来撤销指定commit
  18. # 后者的所有变化都将被前者抵消,并且应用到当前分支
  19. $ git revert [commit ]
  20. # 暂时将未提交的变化移除,稍后再移入
  21. $ git stash
  22. $ git stash pop

十、其他


     
       
       
       
       
  1. # 生成一个可供发布的压缩包
  2. $ git archive

Git分支管理策略

一、主分支Master

首先,代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。

Git主分支的名字,默认叫做Master。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。

二、开发分支Develop

主分支只用来分布重大版本,日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。

这个分支可以用来生成代码的最新隔夜版本(nightly)。如果想正式对外发布,就在Master分支上,对Develop分支进行"合并"(merge)。

Git创建Develop分支的命令:

  git checkout -b develop master

将Develop分支发布到Master分支的命令:

  # 切换到Master分支
  git checkout master

  # 对Develop分支进行合并
  git merge --no-ff develop

这里稍微解释一下,上一条命令的--no-ff参数是什么意思。默认情况下,Git执行"快进式合并"(fast-farward merge),会直接将Master分支指向Develop分支。

使用--no-ff参数后,会执行正常合并,在Master分支上生成一个新节点。为了保证版本演进的清晰,我们希望采用这种做法。关于合并的更多解释,请参考Benjamin Sandofsky的《Understanding the Git Workflow》。

三、临时性分支

前面讲到版本库的两条主要分支:Master和Develop。前者用于正式发布,后者用于日常开发。其实,常设分支只需要这两条就够了,不需要其他了。

但是,除了常设分支以外,还有一些临时性分支,用于应对一些特定目的的版本开发。临时性分支主要有三种:

  * 功能(feature)分支

  * 预发布(release)分支

  * 修补bug(fixbug)分支

这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有Master和Develop。

四、 功能分支

接下来,一个个来看这三种"临时性分支"。

第一种是功能分支,它是为了开发某种特定功能,从Develop分支上面分出来的。开发完成后,要再并入Develop。

功能分支的名字,可以采用feature-*的形式命名。

创建一个功能分支:

  git checkout -b feature-x develop

开发完成后,将功能分支合并到develop分支:

  git checkout develop

  git merge --no-ff feature-x

删除feature分支:

  git branch -d feature-x

五、预发布分支

第二种是预发布分支,它是指发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。

预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式。

创建一个预发布分支:

  git checkout -b release-1.2 develop

确认没有问题后,合并到master分支:

  git checkout master

  git merge --no-ff release-1.2

  # 对合并生成的新节点,做一个标签
  git tag -a 1.2

再合并到develop分支:

  git checkout develop

  git merge --no-ff release-1.2

最后,删除预发布分支:

  git branch -d release-1.2

六、修补bug分支

最后一种是修补bug分支。软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。

修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式。

创建一个修补bug分支:

  git checkout -b fixbug-0.1 master

修补结束后,合并到master分支:

  git checkout master

  git merge --no-ff fixbug-0.1

  git tag -a 0.1.1

再合并到develop分支:

  git checkout develop

  git merge --no-ff fixbug-0.1

最后,删除"修补bug分支":

  git branch -d fixbug-0.1



Git回滚

Git 撤销操作、删除文件和恢复文件

大致介绍

这次来学习对这些文件进行基本的操作,即:

    ◆ 撤销操作

    ◆ 删除文件

    ◆ 恢复文件

我在此之前,已经将三个文件提交到了版本库

撤销操作

撤销操作的语法:

git checkout -- 文件名

撤销操作一般有两种情况:

  ◆ 文件修改后还没有提交到暂存区,进行撤销操作之后,文件恢复到和版本库中一模一样

  ◆文件修改后提交到了暂存区,进行撤销之后,文件恢复到在提交到暂存区之前的状态

现在index.htm中的内容是:

index.html

我们修改他的内容为:

?
1
2
3
4
5
6
7
8
9
  < html lang = "en" >
  < head >
  < meta charset = "UTF-8" >
  < title >Document title >
  head >
  < body >
  body >
  html >

1、文件未提交到暂存区

用 git status 命令查看文件状态

可以看到 index.html 修改了,但是还没有提交到暂存库,我们对这个文件进行撤销操作

然后再打开 index.html 文件,就可以发现,它就恢复到了和版本库中一模一样的状态

2、文件提交到了暂存区,但未提交到版本库

用 git status 命令查看:

如果这个文件写错了,想要修改,但是它已经提交到了暂存区。所以先需要将它撤销到工作区

git reset HEAD 文件名

写入命令并查看文件状态

可以看到,文件已经撤销到了工作区,但是现在文件的内容还没有变化,如果想要恢复到修改之前的状态就使用

git checkout -- 文件名

此时,文件就和版本库中的文件一模一样了

删除文件

新写一个文件,并提交到暂存区

1、先删除工作区中的文件,在删除暂存区的文件

  要先删除工作区中的文件,有两种方式:

   ◆ 只在文件夹中删除

   ◆用命令行

rm 文件名

删除工作区的文件后,查看文件状态:

可以看到,工作区中的 game.js 删除了,但是暂存区中的 game.js 还未删除

删除暂存区中的文件:

git rm 文件名

如图:

这样就将两个去的文件都删除了

2、同时删除工作区和暂存区中的文件

git rm -f 文件名

如图:

3、删除暂存区的文件,不删除工作区的文件

git rm --cached 文件名

如图:

恢复文件

如果我们想要恢复某个文件或者整个项目到之前的某个版本,Git提供了方便的操作

可以使用 git log 查看版本库的信息

如图:

如果想要将某个文件恢复到某个版本时的状态,可以使用以下的命令:

git checkout id 文件名

其中的id是图中框出来的,例如要将 index.html 文件恢复到 add three files 版本时的状态:

id可以不用全部复制过来,复制一部分就可以了

如果要将所有的文件都恢复到某个版本,可以使用下面的命令

git reset --hard id

如图:

除了用id恢复到某个版本库时的状态,还有别的写法:

?
1
2
3
4
//恢复到上一个版本
git reset --hard HEAD^
// 恢复到前两个版本
git reset --hard HEAD~2

另外,可以用 git reflog 查看恢复的记录



Git版本控制:Git查阅、撤销文件修改和撤销文件追踪

历史版本对比

查看日志git log

查看某一历史版本的提交内容git show 4ebd4bbc3ed321d01484a4ed206f18ce2ebde5ca,这里能看到版本的详细修改代码。

对比不同版本git diff c0f28a2ec490236caa13dec0e8ea826583b49b7a 2e476412c34a63b213b735e5a6d90cd05b014c33

push之前可以使用git diff origin/dev...HEAD --name-status查看要push的内容有没有改变。

[Git高级教程git log与git relog]

git reset命令参数

包括 --mixed,--soft --hard等,其中--mixed为默认方式,他们之间的区别如下
git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息
git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可
git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容
git reset -soft :取消了commit  
git reset  --mixed(默认) :取消了commit ,取消了add。Your branch is ahead of 'origin/master' by 1 commit.不小心commit大文件,但是push失败,使用git log找到上一次的版本号,再使用git reset --mixed 版本号就可以了。
git reset -hard :取消了commit ,取消了add,取消源文件修改。

重置文件

在git中,有3种类型的重置。重置是让文件回到git历史中的一个特定版本。

  1. git reset –hard {{some-commit-hash}} —— 回退到一个特定的历史版本。丢弃这次提交之后的所有变更。
  2. git reset {{some-commit-hash}}—— 回滚到一个特定的历史版本。将这个版本之后的所有变更移动到“未暂存”的阶段。这也就意味着你需要运行 git add . 和 git commit 才能把这些变更提交到仓库.
  3. git reset –soft {{some-commit-hash}} ——回滚到一个特定的历史版本。将这次提交之后所有的变更移动到暂存并准备提交阶段。意味着你只需要运行 git commit 就可以把这些变更提交到仓库。

这些命令似乎并没有什么用处,但当你尝试着将文件在不同版本间移动时,使用它们会非常方便。

使用重置的一些用例如下:

  1. 如果想清除变更记录,可以使用清理命令——git reset –hard HEAD (最常用)
  2. 如果想编辑,以不同的顺序,重新暂存,重新提交文件—— git reset {{some-start-point-hash}}
  3. git reset –soft {{some-start-point-hash}}如果想把之前3次的提交,作为一次提交 git reset –soft {{some-start-point-hash}}

皮皮Blog



git单个文件删除和恢复

{针对文件删除及恢复}
删除文件跟踪并且删除文件系统中的文件file git rm file
提交刚才的删除动作,之后git不再管理该文件git commit
删除文件跟踪但不删除文件系统中的文件file git rm --cached file
Note:--cached Use this option to unstage and remove paths only from the index.Working tree files, whether modified or not, will beleft alone.只是将文件从暂存区去除(不影响工作区对应的文件)。
[ git-rm - Remove files from the working tree and from the index]
提交刚才的删除动作,之后git不再管理该文件。但是文件系统中还是有file。 git commit
[ Git版本控制教程 - Git本地仓库:删除文件]

本地文件被旧的远程文件覆盖怎么撤销修改

git reflog ,找到同步前的提交,git reset 就可以了

git rm 之后的文件如何还原

执行$git rm createGraph.py删除文件createGraph.py后,发现删除错了。
解决方案1:
$git status
...
Changes to be committed:
  (use "git reset HEAD ..." to unstage)
    deleted:    createGraph.py
可以看到提示先使用git reset HEAD ...来unstage文件
$ git reset HEAD createGraph.py
Unstaged changes after reset:
D    createGraph.py
再查看一下
$git status
...
Changes not staged for commit:
  (use "git add/rm ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)
    deleted:    createGraph.py
可以看到提示先使用git checkout -- ...来丢弃文件的修改
$ git checkout -- createGraph.py
这样就恢复了rm了的文件
$ls
createGraph.py
解决方案2:
git rm README
git status
$ git stash list
stash@{0}: WIP on master: bfcdf14 test git
#拿出来使用 git stash pop
git stash pop
[ Git高级教程:git stash]
解决方案3:
这时可以直接使用git log; git reset --hard "commit id"恢复到上一个commit,但是这样不好,我只想恢复删除的那一个文件,要是commit之间做了很多改动,恢复到上一个commit会将其它文件的修改都恢复了。要对单个文件修改。
首先查看该文件的历史版本信息:git log  [email protected]

记录下需要恢复的commit版本号:如 9aa51d89799716aa68cff3f30c26f8815408e926
恢复该文件:git reset 9aa51d89799716aa68cff3f30c26f8815408e926 [email protected]
提交git:git commit -m "revert old file"
测试了一下,发现文件根本没有改动,只是有unstaged commit的提示(说明一下,我是在windows环境下使用git客户端,linux不知道是不是同样的问题),并且,一旦执行“git add .”,所有暂存区中的变化全都消失了。
尝试执行git checkout命令,因为这个命令平时只适应于将文件恢复到上次递交的状态,而不能选择递交的版本。
虽然执行完毕后什么提示都没,但是查看文件可以看到,文件已经被修改为历史版本了。
总结:git将单个文件恢复到历史版本的正确方法如下:
   git reset commit_id 文件路径
   git checkout -- 文件路径
[ GIT 恢复单个文件到历史版本]

皮皮Blog



版本回退-撤销文件修改

{针对文件修改恢复}

工作区修改一个文件后,又想回到修改前(git add前)

1. 当然可以直接手动再在工作区中将文件修改回去

2. 修改后,通过命令git status查看

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

这时Git会告诉你,git checkout -- file可以丢弃工作区的修改:

$ git checkout -- readme.txt

Note:

1. git checkout -- file命令中的--很重要,没有--,就变成了“切换到另一个分支”的命令,我们在后面的分支管理中会再次遇到git checkout命令。

2. 命令git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:

一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。总之,就是让这个文件回到最近一次git commit或git add时的状态。

3. 工作区、暂存区的概念不清楚的可见于Git版本控制教程 - Git本地仓库

如果在工作区中修改了文件还git add到暂存区(但是在commit之前)

用git status查看一下,修改只是添加到了暂存区,还没有提交:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       modified:   readme.txt
#

Git同样告诉我们,用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区:

$ git reset HEAD readme.txt
Unstaged changes after reset:
M       readme.txt

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

再用git status查看一下,现在暂存区是干净的,工作区有修改。

然后丢弃工作区的修改
$ git checkout -- readme.txt

$ git status
# On branch master
nothing to commit (working directory clean)

不但修改了文件还从暂存区提交commit到了版本库 - 版本回退

版本回退可以回退到上一个版本。不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。Git是分布式版本控制系统。

在工作中对某个文件(如readme.txt)进行多次修改交commit。

可以通过版本控制系统命令告诉我们提交的历史记录,在Git中,我们用git log命令查看:

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <[email protected]>
Date: Tue Aug 20 15:11:49 2013 +0800
append GPL

commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <[email protected]>
Date: Tue Aug 20 14:53:12 2013 +0800

add distributed

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date: Mon Aug 19 17:51:55 2013 +0800

wrote a readme file
Note:

1. git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是wrote a readme file

2. 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数:

$ git log --pretty=oneline

3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

3. 你看到的一大串类似3628164…882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

4. 每提交一个新版本,实际上Git就会把它们自动串成一条时间线。如果使用可视化工具(如GitX、github的客户端、pycharm)查看Git历史,就可以更清楚地看到提交历史的时间线。0

现在我们想要把readme.txt回退到上一个版本

如“add distributed”的那个版本,怎么做呢?首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交3628164…882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

现在,我们要把当前版本“append GPL”回退到上一个版本“add distributed”,就可以使用git reset命令:


  
    
    
    
    
  1. KaTeX parse error: Expected 'EOF', got '#' at position 27: …n style="color:#̲33cc00;"> git log
    commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
    Author: Michael Liao <[email protected]>
    Date: Tue Aug 20 14:53:12 2013 +0800
    add distributed
    

commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <[email protected]>
Date: Mon Aug 19 17:51:55 2013 +0800

wrote a readme file

最新的那个版本append GPL已经看不到了!

恢复文件后,要是我们又想回到修改后的文件呢?(命令行窗口还没有被关掉)

{这个是git reset --hard后,又反悔了,想回到修改后的状态}

只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPLcommit id3628164...,于是就可以指定回到未来的某个版本:

$ git reset --hard 3628164

HEAD is now at 3628164 append GPL

版本号没必要写全,前几位就可以了,Git会自动去找。

Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:

git-head

改为指向add distributed:

git-head-move

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

恢复文件后,要是我们又想回到修改后的文件呢?(命令行窗口早就关掉了)

{这个是git reset --hard后,又反悔了,想回到修改后的状态}

想恢复到新版本怎么办?找不到新版本的commit id怎么办?当你用$ git reset --hard HEAD^回退到add distributed版本时,再想恢复到append GPL,就必须找到append GPL的commit id。

Git提供了一个命令git reflog用来记录你的每一次命令:[Git高级教程:git log与git reflog]

$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file

第二行显示append GPL的commit id是3628164,现在,你又可以乘坐时光机回到未来了。


git 撤销文件追踪

git忽略已经被提交的文件/文件夹

{git 对于 已经添加到版本库的文件设置忽略}

问题

git commit时候忘记设置ignore了,于是commit了一个相当大的文件,git push时候,因为要push大文件,可能会出错,也可能push好久还没好。
如果直接删除掉大文件,再push还是同样问题;如果把大文件放到忽略文件里,再push,还是这样的问题不变。
几种解决方案:

终极解决方案1

适用于这个文件是最近一次commit的,并且git commit的其它内容(如小文件)也回退。

一旦发现git push了大文件失败了,就使用下面命令回退这次commit,再添加.gitignore再add 和 commit。

git reset  --mixed(默认) :取消了commit ,取消了add。Your branch is ahead of ‘origin/master’ by 1 commit.不小心commit大文件,但是push失败,使用git log找到上一次的版本号,再使用git reset --mixed 版本号就可以了。

终极解决方案2

git当push100M以上文件,就直接拒绝你的push,要想push必须把该文件从本地仓库和远程仓库全部移除到commit外。
注意此方法 适用于这个文件是最近一次commit的{包括已经push到github了(所以要先git pull)} 并且希望git commit的其它内容(如小文件)不回退。
git rm --cached /XXX/XXX/libbaiduNaviSDK.a(加下划线部分是你自己的要移除的文件的路径)
find . -size +100M ! -path “git” | xargs git rm --cached
git commit --amend -CHEAD
find . -size +100M ! -path “git” | mv /tmp/tmpgit
git pull
git push
下次再add时
先添加大文件到.gitignore
mv /tmp/tmpgit .
再git add .
git commit -m 'del -size +100M’
git push
Note: 
第一步:将文件从暂存区去除;
第二步:是修改提交,也就是用这次删除了大文件的暂存区的新的commit覆盖上次大文件的commit;
第三步:移除之前的大文件(或者是想删除之前commit上的文件);
第四步:如果不执行干什么都会提示:On branch master Your branch and ‘origin/master’ have diverged,and have 1 and 1 different commits each, respectively.  (use “git pull” to merge the remote branch into yours)nothing to commit, working tree clean
第五步:添加大文件不加入git版本控制
第七步:commit
执行完这步后,这个大文件将会从你的commit记录里和add移除(也就是不会再出现在stage暂存区或者master中,这些大于100M的文件会回到git add .之前的状态,相当于没有git add,成为untracked files),这时候就可以git push把本地代码push到github上了。
记得加.ignore或者回到git lfs中来上传大文件![ Git版本控制:Git高级教程]
[ Removing a file added in the most recent unpushed commit]
[ Working with large files]
如果是前几次提交的git commit了大文件,这时上面的修改可能包含了对大文件的处理过程(这样就可逆对大文件的commit了?),还是会上传对大文件的修改。如:
$ git diff origin/master --name-statusA       JIM/business_result.json #并没有大文件会push
A       JIM/yelp_academic_dataset_business.json
A       JIM/yelp_academic_dataset_tip.json
但是git push时怎么还是上传的这个大文件,这难道是因为git diff比较的只是当前commit和远程,而本地实际有两个commit版本,大文件存在于前一个版本中,所以只要有就会上传
remote: error: Trace: 4cbb68625000edd0054cf593be3f7058
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File JIM/test_candidate.dat is 188.52 MB; this exceeds GitHub’s file size limit of 100.00 MB
这时只能使用下面的终极解决方案2了,前本地commit所有版本中的大文件都del掉。

终极解决方案3

此方法适用于这个文件是前几次commit的

git filter-branch --tree-filter

如commit了一个EpipeCpu/ipch目录下的大文件, 现在要push但是仅想删去commit中的这个目录。
KaTeX parse error: Expected 'EOF', got '#' at position 20: …n style="color:#̲FF0000;">git fi…git rm --cached FILENAME
如果后面跟的是目录就加上个 -r  就行,(这个操作不会删除这个文件)git rm -r --cached DIR_NAME
然后更新info/exclude或者.gitignore忽略掉目标文件,不知道怎么操作的可参见[ Git版本控制教程 - Git本地仓库:忽略指定文件]
最后 git commit -m “dont track”     还是 git commit --amend -CHEAD ?
成功之后会提示:
* file changed …
delete mode … FILENAME
检查一下,git status,提示nothing commit…就说明成功删除文件的追踪。如果显示untracked file FILENAME,可能是ignore文件出错,解决参见[ Git版本控制教程 - Git本地仓库:忽略指定文件]。
当然如果你后悔了,从ignore文件中删除FILENAME,再直接git add .就可以了,然后git commit,可能会提示没有什么变化。
[ .gitignore not working]
[ 处理GitHub不允许上传大于100M文件问题]
[ git忽略已经被提交的文件]

究极解决方案:本地重建并取代远程

lz碰到一个很烦人的,git rm --cached bigfile并且ignore后,使用git diff查看明明没有大文件,所有要提交的大文件都是D(delete模式),难道delete的文件也要上传?还是之前add大文件后再git rm cached后有两个操作,add再delete,可是git diff里面并没有add大文件,不知道为什么总是有那个大文件上传,总是!用了无数方法总是有这个大文件targetopinion/dist/TargetOpinionMain.exe:
git diff查看是没有TargetOpinionMain.exe文件add的,也是奇怪。ps:lz曾经将这个大文件从nlp/dist移动到nlp/targetopinion/dist中,然后路径中git rm --cached不能作用于dist,而可以作用于targetopinion/dist,但是怎么说那个targetopinion/dist中的exe大文件是没有的!可是它总是有!搞了好久,lz只能采取下面的极限方法了:
删除本地nlp目录下的.git文件夹
重新设置本地git管理:git init
git remote add origin [email protected]?**
git add .
git commit -m 'init commit’
git push -u --force origin 分支名
这里是强制提交,本来要git pull的,但是这样可能覆盖本地文件,要是完全不想要远程的文件了,可以这样,用本地取代远程的文件(结果导致远程主机上更新的版本被覆盖)。git push见[ Git版本控制教程 - Git远程仓库:–force选项]
这个其实不就是“如何删除github上的一个项目的内容,重新提交所有内容”吗?[ 如何删除github上的一个项目的内容,重新提交所有内容]

修改最后一次提交git commit --amend

{还有一种有条件但是更简单快捷的解决方案:git commit --amend 修改上一次的提交信息,这是最快最好的方法,不过如果不是针对上一次提交那就不好了!}
有时候用 git commit -m 提交时,可能没写好或者误操作导致提交的信息不合适,但你还没有 push 到远程分支时,可以使用 git commit --amend 修改上一次的提交信息。
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:
$ git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:
$ git commit -m ‘initial commit’
$ git add forgotten_file
$ git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容。
[ git commit –amend 修改还未提交到远程分支的 commit 信息]

git update-index

这种方法好像有问题,不推荐
git update-index --assume-unchanged




你可能感兴趣的:(qunar.start)