Git复习整理

不用登陆,设置一次用一辈子

gitbash不支持CTRL+v

gitbash用的是linux命令

创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录

然后,转到这个目录,执行

$ git init才对

把文件添加到版本库

第一步,用命令git add告诉Git,把文件添加到仓库:

$ git add readme.txt

必须要在仓库目录下才行

可以add多次

第二步,用命令git commit告诉Git,把文件提交到仓库:

$ git commit -m "wrote a readme file"

[master (root-commit) eaadf4e] wrote a readme file

 1 file changed, 2 insertions(+)

 create mode 100644 readme.txt

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

git status命令可以让我们时刻掌握仓库当前的状态

git diff顾名思义就是查看difference,显示的格式正是Unix通用的diff格式

用git log命令查看历史记录

在Git中,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。

使用git reset命令回退到上一个版本

指定回到未来的某个版本,需要其版本号,一部分就成,然后用git reset就成

Git提供了一个命令git reflog用来记录你的每一次命令

git checkout -- file可以丢弃工作区的修改不管有没有放到暂存区

命令git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区

命令git rm删除文件,并git commit先手动删除文件,然后使用git rm <file>和git add<file>效果是一样的。

另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:

$ git checkout -- test.txt

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

删除有两种方式: 1、工作区内"rm 文件名",然后"git rm 文件名",然后"git commit -m '备注'" 2、直接使用"git rm 文件名",然后"git commit -m '备注'" 实验结果: 1、工作区内"rm 文件名" 只是删除工作区内容,暂存区内容还是在的,在"git rm 文件名"操作之前可通过"git checkout --文件名"从暂存区进行恢复。 2、"git rm 文件名"是既删除工作区内容也删除暂存区内容的,所以在"git commit -m '备注'"操作之前可以通过"git checkout HEAD -- 文件名"从版本库进行恢复,当然你要是直接用git reset HEAD^也行但是可能会影响你其他修改但是未提交的其他内容的

$ git remote add origin [email protected]:账户名/远程仓库名.git

一般把远程库与本地库取名一致才好

若出现错误,先执行$ git remote rm origin,再执行上面语句就好

本地和远程的文件应该合并后才能上传本地的新文件,但是新建的项目还没有文件,空的,就不能往下拉了,直接把本地修改的文件上传即可

1、先拉下来,会自动合并的(不用操心)

git pull origin master

2、再上传

git push -u origin master

成功解决问题

refusing to merge unrelated histories

是两个不同的项目,要把两个不同的项目合并,git需要添加一句代码,在git pull,这句代码是在git 2.9.2版本发生的,最新的版本需要添加--allow-unrelated-histories

必须要建立一个没有被初始化的库才行,也就是没有readme.md的文件

先创建远程库,再从远程库克隆,这时要选一个合适的路径了 ,是在此路径下新建立一个文件夹,并把内容都放在里面

git push -u origin master

git clone [email protected]:heroisuseless/helloworld.git

git pull origin master

HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是当前分支。

一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

首先,我们创建dev分支,然后切换到dev分支:

$ git checkout -b dev

Switched to a new branch 'dev'

然后,用git branch命令查看当前分支:

$ git branch

* dev

  master

切换回master分支后,再查看一个readme.txt文件,刚才添加的内容不见了!因为那个提交是在dev分支上,而master分支此刻的提交点并没有变:

现在,我们把dev分支的工作成果合并到master分支上:

$ git merge dev

Updating d46f35e..b17d20eFast-forward

 readme.txt | 1 +

 1 file changed, 1 insertion(+)

git merge命令用于合并指定分支到当前分支

合并完成后,就可以放心地删除dev分支了:

$ git branch -d devDeleted branch dev (was b17d20e).

删除后,查看branch,就只剩下master分支了:

$ git branch

* master

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

这个只是针对不同文件而言,对于在不同分支上修改同一文件后,就必须手动修改文件改正,某一分支中的文件,使两个文件相同,这样才会解决冲突继续提交

分支管理策略

阅读: 473794

通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

下面我们实战一下--no-ff方式的git merge:

首先,仍然创建并切换dev分支:

$ git checkout -b devSwitched to a new branch 'dev'

修改readme.txt文件,并提交一个新的commit:

$ git add readme.txt

$ git commit -m "add merge"

[dev f52c633] add merge

 1 file changed, 1 insertion(+)

现在,我们切换回master:

$ git checkout masterSwitched to branch 'master'

准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward:

$ git merge --no-ff -m "merge with no-ff" devMerge made by the 'recursive' strategy.

 readme.txt | 1 +

 1 file changed, 1 insertion(+)

因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。

合并后,我们用git log看看分支历史:

$ git log --graph --pretty=oneline --abbrev-commit

*   e1e9c68 (HEAD -> master) merge with no-ff

|\  

| * f52c633 (dev) add merge

|/  

*   cf810e4 conflict fixed

...

可以看到,不使用Fast forward模式,merge后就像这样:

分支策略

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

下面我们实战一下--no-ff方式的git merge:

首先,仍然创建并切换dev分支:

$ git checkout -b devSwitched to a new branch 'dev'

修改readme.txt文件,并提交一个新的commit:

$ git add readme.txt

$ git commit -m "add merge"

[dev f52c633] add merge

 1 file changed, 1 insertion(+)

现在,我们切换回master:

$ git checkout masterSwitched to branch 'master'

准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward:

$ git merge --no-ff -m "merge with no-ff" devMerge made by the 'recursive' strategy.

 readme.txt | 1 +

 1 file changed, 1 insertion(+)

因为本次合并要创建一个新的commit,

Git还提供了一个stash功能,可以把当前工作现场“储藏”起来,等以后恢复现场后继续工作:

$ git stash

Saved working directory and index state WIP on dev: f52c633 add merge

用于在dev上进行工作时,创建了一个bug分支,这样可以把dev场景保存起来

首先确定要在哪个分支上修复bug,假定需要在master分支上修复,就从master创建临时分支,但肯定不会在master分支上进行工作的:

$ git checkout masterSwitched to branch 'master'Your branch is ahead of 'origin/master' by 6 commits.

  (use "git push" to publish your local commits)

$ git checkout -b issue-101Switched to a new branch 'issue-101'

bug分支实际上是一个超前分支

一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;

另一种方式是用git stash pop,恢复的同时把stash内容也删了

如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

要查看远程库的信息,用git remote或者,用git remote -v显示更详细的信息

$ git remote

origin

远程仓库的默认名称是origin

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

$ git push origin master

如果要推送其他分支,比如dev,就改成:

$ git push origin dev

如果你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

· 这就是rebase操作的特点:把分叉的提交历史“整理”成一条直线,看上去更直观。缺点是本地的分叉提交已经被修改过了。

rebase操作可以把本地未push的分叉提交历史整理成直线;

· 

· 

rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

· 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。所以,标签也是版本库的一个快照。

$ git branch

* dev

  master$ git checkout masterSwitched to branch 'master'

然后,敲命令git tag <name>就可以打一个新标签:

$ git tag v1.0

可以用命令git tag查看所有标签:

$ git tag

v1.0

$ git tag v0.9 f52c633

标签不是按时间顺序列出,而是按字母排序的。可以用git show <tagname>查看标签信息

还可以创建带有说明的标签,用-a指定标签名,-m指定说明文字:

$ git tag -a v0.1 -m "version 0.1 released" 1094adb

用命令git show <tagname>可以看到说明文字

如果标签打错了,也可以删除:

$ git tag -d v0.1Deleted tag 'v0.1' (was f15b0dd)

因为创建的标签都只存储在本地,不会自动推送到远程。所以,打错的标签可以在本地安全删除。

如果要推送某个标签到远程,使用命令git push origin <tagname>:

$ git push origin v1.0Total 0 (delta 0), reused 0 (delta 0)To github.com:michaelliao/learngit.git

 * [new tag]         v1.0 -> v1.0

或者,一次性推送全部尚未推送到远程的本地标签:

$ git push origin --tagsTotal 0 (delta 0), reused 0 (delta 0)To github.com:michaelliao/learngit.git

 * [new tag]         v0.9 -> v0.9

如果标签已经推送到远程,要删除远程标签就麻烦一点,先从本地删除:

$ git tag -d v0.9Deleted tag 'v0.9' (was f52c633)

然后,从远程删除。删除命令也是push,但是格式如下:

$ git push origin :refs/tags/v0.9To github.com:michaelliao/learngit.git

 - [deleted]         v0.9

在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。如果你确实想添加该文件,可以用-f强制添加到Git

甚至还有人丧心病狂地把lg配置成了:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

猜你喜欢

转载自blog.csdn.net/HeroIsUseless/article/details/81429632