git - QLGQ/learning-python GitHub Wiki
- 要随时掌握工作区的状态,使用git status命令。
- 如果git status告诉你有文件被修改过,用git diff 可以查看修改内容。
- 当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。git checkout -- file其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。(命令git checkout .将本地所有修改的或删除的没有提交的都返回原状态。)
- 当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了上述的要修改的情况,第二步就按上述场景操作。
- 已经提交了不合适的修改到版本库时,想要撤销本次提交,需要版本回退,不过前提是没有推送到远程库。
- 版本控制系统中命令git log可以查看提交历史记录,该命令执行后会显示从最近到最远的提交日志。如果嫌输出信息太多,看的眼花缭乱,可以加上--pretty=oneline参数。
- 命令git rm用于删除一个文件,该操作是从版本库中删除文件,并用git commit提交说明该删除命令。而一般情况下,通常直接在文件管理器中把没用的文件删了,或者rm命令删了,这个时候Git知道你删除了文件,因此,工作区和版本库就不一致了。git status命令会立刻告诉你那些文件被删除了。
- 命令git diff HEAD -- file命令可以查看工作区和版本库里面最新版本的区别。
- 命令git add -A把工作区所有的文件都添加到暂存区。
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然上100个版本写100个^比较容易数不过来,所以就写成HEAD~100。现在我们要把当前版本回退到上一个版本,就可以使用git reset命令:
git reset --hard HEAD^
如果想再回去,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找,找到之前版本的commit id,于是就可以指定回到未来的某个版本。版本号没必要写全,前几位就可以,Git会自动找全。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。如果命令行被关闭,要重返未来,可用git reflog查看历史命令,以便确定要回到未来的哪个版本。
- HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
- 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
- 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
要关联一个远程库,使用命令
git remote add origin git@server-name:path/repo-name.git
关联后,使用命令
git push -u origin master
第一次推送master分支的所有内容;此后,每次本地提交后,只要有必要吗,就可以使用命令
git push origin master
推送最新修改
要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。 git clone命令如下:
git clone git@server-name:path/repo-name.git
- 查看分支: git branch
- 创建分支: git branch
- 切换分支: git checkout
- 创建+切换分支:git checkout -b
- 合并某分支到当前分支: git merge
- 删除分支:git branch -d
当Git 无法自动合并分支时,就必须首先解决冲突。解决冲突之后,再提交,合并完成。用"git log --graph --pretty=oneline --abbrev-commit"命令可以看到分支合并图。
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。你可以多次stash,恢复的时候,先用git stash listc查看,然后恢复指定的stash,用命令:
$ git stash apply stash@{0}
工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;另一种方式是用git stash pop,恢复的同时把stash内容也删了。
来发一个新feature,最好新建一个分支;如果要丢弃一个没有被合并过的分支,可以通过git branch -D 强行删除。
因此,多人协作的工作模式通常是这样: 1. 首先,可以试图用git push origin branch-name推送自己的修改; 2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并; 3. 如果合并有冲突,则解决冲突,并在本地提交; 4. 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功! 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream branch-name origin/branch-name。 这就是多人协作的工作模式,一旦熟悉了,就非常简单。
- 查看远程库信息,使用git remote -v;
- 本地新建的分支如果不推送到远程,对其他人就是不可见的;
- 从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
- 在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
- 建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;
- 从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。
- 当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支。可以用git branch命令查看。
- 修改命令
git remote origin set-url [url]
- 先删后加
git remote rm origin
git remote add origin [url]
- 直接修改config文件
- 删除untracked files
git clean -f
- 连untracked的目录也一起删掉
git clean -fd
- 连gitignore的untracked文件/目录也一起删掉(慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
在用上述 git clean 前,强烈建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nfd
git clean -nf
仅reset index,但是不reset woking directory。这个模式是默认模式,即当不显示告知git reset模式时,会使用mixed模式。这个模式的效果是,working directory中文件的修改都会被保留,不会丢弃,但是也不会被标记为"Changes to be committed",但是会打出什么还未被暂存的报告。
重置后取消暂存的变更(Unstaged changes after reset):
M README.md
M cabbage/api/log.py
M cabbage/api/task.py
M cabbage/rest/adapter.py
M cabbage/services/face_recognition/face_api.py
M cabbage/services/mfa/otp.py
M cabbage/services/saml_app/__init__.py
M cabbage/services/saml_app/sso.py
M config.py
M requirements.txt
重设(reset)index和working directory,自从以来在woking directory中的任何改变都被丢弃,并把HEAD指向。 具体实例,如下,假设有三个commit:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
执行git reset --hard HEAD~1后,显示: HEAD is now at commit2。运行git log:
commit2: add test2.c
commit1: add test1.c
运行git status,没有任何变化。
index和working directory中的内容不做任何改变,仅仅把HEAD指向。这个模式的效果是,执行完毕后,自从以来的所有改变都会显示在git status的"Changes to be committed"中。
具体实例如下,假设有三个commit:
commit3: add test3.c
commit2: add test2.c
commit1: add test1.c
执行git reset --soft HEAD~1后,运行git log:
commit2: add test2.c
commit1: add test1.c
运行git status,则test3.c处于暂存区,处于准备提交状态。即此时git commit就会提交它。
对于已经把代码push到线上仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指定的版本,线上,线下代码保持一致.你要用到下面的命令:
revert
git revert用于反转提交,执行evert命令时要求工作树必须是干净的.
git revert用一个新提交来消除一个历史提交所做的任何修改.
revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新.(这里不会像reset造成冲突的问题)
git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit.
git stash可用来暂存当前正在进行的工作,比如想pull最新代码,又不想加新commit,或者另外一种情况,为了fix一个紧急的bug,先stash,使返回到自己上一个commit,改完bug之后再stash pop,继续原来的工作。
基础命令:
- git stash
- do some work
- git stash pop
当你多次使用git stash命令后,你的栈里将充满了未提交的代码,这时候你会对将哪个版本应用回来有些困惑,git stash list
命令可以将当前的Git栈信息打印出来,你只需要找到对应的版本号,例如使用git stash apply stash@{1}
就可以将你指定版本号为stash@{1}的工作取出来,当你将所有的栈都应用回来的时候,可以使用git stash clear
来将栈清空。
git stash # save uncommitted changes
# pull, edit, etc.
git stash list # list stashed changes in this git
git show stash@{0} # see the last stash
git stash pop # apply last stash and remove it from the list
git stash --help # for more info
用git rm来删除文件,同时还会将这个删除操作记录下来;而用rm来删除文件,仅仅是删除了物理文件,没有将其从git的记录中剔除。
直观地来讲,git rm删除过的文件,执行git commit -m "abc"
提交时,会自动将删除该文件的操作提交上去。而对于用rm命令直接删除的文件,执行git commit -m "abc"
提交时,则不会将删除该文件的操作提交上去。不过不要紧,即使你已经通过 rm 将某个文件删除掉了,也可以再通过 git rm 命令重新将该文件从 git 的记录中删除掉,这样的话,在执行 git commit -m "abc" 以后,也能将这个删除操作提交上去。如果之前不小心用 rm 命令删除了一大批文件呢?是的,此时用 git rm 逐个地再删除一次就显得相当麻烦了。不过还有更方便的处理方案,用如下的方式做提交就没有问题了: git commit -am "abc"。
在被 git 管理的目录中删除文件时,可以选择如下两种方式来记录删除动作:
rm + git commit -am "abc"
git rm + git commit -m "abc"
另外,git add . 仅能记录添加、改动的动作,删除的动作需靠 git rm 来完成。
-
git add .
:它会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容修改(modified)以及新文件(new),但不包括被删除的文件。 -
git add -u .
:它仅监控已经被add的文件(即tracked file),它会将已跟踪的被修改的文件和(或)删除的文件提交到暂存区。注意这些被删除的文件被加入到暂存区再被提交并推送到服务器的版本库之后这个文件就会从git系统中消失了。add -u不会提交新文件(untracked file)。(git add --update的缩写) -
git add -A .
:表示将所有的已跟踪的文件的修改与删除和新增的未跟踪的文件都添加到暂存区,是上面两个功能的合集(git add --all的缩写)