本博客主要参考了https://blog.csdn.net/qq_36150631/article/details/81038485,并加入了自己的一些理解。
现在的情景是:我们已经在本地创建了一个Git仓库后,又想在github创建一个Git仓库,并且希望这两个仓库进行远程同步,这样github的仓库可以作为备份,又可以其他人通过该仓库来协作。
首先,登录github上,然后在右上角找到“create a new repo”创建一个新的仓库,名为testgit。。
目前,在GitHub上的这个testgit仓库还是空的,我们可以从这个仓库克隆新的仓库到本地,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
这里我们选择后者,先将本地仓库与远程仓库关联,然后再讲本地仓库的所有内容推送到远程仓库。
关联远程仓库:
git remote add origin https://github.com/xiaowei582648206/myAnsible.git
origin代表这个远程仓库主机地址的简写。类似域名解析。
把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。
git push -u origin master:master
由于远程库是空的,我们第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在github页面中看到远程库的内容已经和本地一模一样了,上面的要输入github的用户名和密码.
总结创建与合并分支命令如下:
查看分支:git branch
创建分支:git branch name
切换分支:git checkout name
创建+切换分支:git checkout –b name
合并某分支到当前分支:git merge name
删除分支:git branch –d name
git add file.txt 将修改过后的file.txt 添加到缓冲区后,就可以通过commit将缓冲区的内容提交到本地的repository库中了。
分支策略:首先master主分支应该是非常稳定的,也就是用来发布新版本,一般情况下不允许在master上面干活,干活一般情况下在新建的dev分支上干活,干完后,比如上要发布,或者说dev分支代码稳定后可以合并到主分支master上来。
在开发中,会经常碰到bug问题,那么有了bug就需要修复,在Git中,分支是很强大的,每个bug都可以通过一个临时分支来修复,修复完成后,合并分支,然后将临时的分支删除掉。
3.分支管理策略。
通常合并分支时,git一般使用”Fast forward”模式,在这种模式下,删除分支后,会丢掉分支信息,现在我们来使用带参数 –no-ff来禁用”Fast forward”模式。首先我们来做demo演示下:
创建一个dev分支。
修改readme.txt内容。
添加到暂存区。
切换回主分支(master)。
合并dev分支,使用命令 git merge –no-ff -m “comment” dev
查看历史记录
4.多人协作。
当你从远程库克隆时候,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且远程库的默认名称是origin。
要查看远程库的信息 使用 git remote
要查看远程库的详细信息 使用 git remote –v
git push <远程git库完整库名> <本地分支>:<远程分支>
推送分支:
推送分支就是把该分支上所有本地提交(commit)推送到远程库对应的分支中,推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
使用命令 git push origin master:master //将本地master 分支推送到远程master分支上,本地分支和远程分支之间用冒号连接。
如果我们现在要推送到其他分支,比如dev分支上,我们还是那个命令
git push origin dev:dev //将本地dev分支推送到远程的dev分支上
(1)、git pull <远程主机> <远程分支>:<本地分支> //将远程分支拉取到本地,并与本地分支合并
(2)、git pull <远程主机> <远程分支> //将远程分支拉取到本地,并与当前分支合并,可省略本地分支
(3)、git pull <远程主机> //本地的当前分支自动与对应的origin主机追踪分支(remote-tracking branch)进行合并。
注:git pull origin next相当于 git fetch origin 和 git merge origin/next,即先将远程分支next抓取fetch到本地,然后将next分支与当前分支合并merge。
在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。
Git也允许手动建立追踪关系。
git branch --set-upstream master origin/next
将本地master分支与远程的next分支建立tracking关系
如果当前分支与与远程分支存在追踪关系,git pull就可以省略远程分支名和本地分支名
git pull origin //将当前分支与自动对应的远程追踪分支进行合并
(4)、git pull //如果当前分支只有一个追踪分支,连远程主机名都可以省略。该命令表示,当前分支自动与唯一一个追踪分支进行合并
注:每次工作之前,先把远程库的最新的内容pull下来,可以立刻看到别人的改动,然后在前人的工作基础上开始一天的工作,这是一个好习惯!!!另外所有的push操作,只有在pull之后才能进行,换句话来说就是你本地的分支必须先拥有远程分支所有的东西之后,才允许你提交新的修改内容。
(1)、git push <远程主机> <本地分支>:<远程分支> //将本地分支推送指定的远程分支
(2)、git push <远程主机> <本地分支> //如果远程分支被省略,则表示将本地分支推送到与之存在追踪关系的远程分支(通常两者同名),如果该远程分支不存在,则会被新建
(3)、git push <远程主机> :<远程分支> //如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支,等同于 git push origin --delete master
(4)、git push <远程主机> //如果当前分支与远程分支存在追踪关系(tracking),则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支
(5)、git push //如果当前分支只有一个远程分支,那么主机名都可以省略,形如 git push,可以使用git branch -r ,查看远程的分支名
总结一点:所有的git push 和 git pull 命令,一旦省略本地分支,那么就意味着命令作用的对象是本地当前分支。如果不放心就把命令写完整,指定好远程分支和本地分支。
git fetch和git pull的区别
(1)、git fetch:相当于是从远程获取最新版本到本地,不会自动合并。
git fetch origin master
git log -p master..origin/master
git merge origin/master
以上命令的含义:
•首先从远程的origin的master主分支下载最新的版本到origin/master分支上
•然后比较本地的master分支和origin/master分支的差别
•最后进行合并
上述过程其实可以用以下更清晰的方式来进行:
git fetch origin master:tmp
git diff tmp
git merge tmp
(2)、git pull:相当于是从远程获取最新版本并merge到本地
git pull origin master
上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并。
(1)、今天主要想测试一下,如果远程库的内容比本地库的内容要新,是否可以直接将本地的内容push到远程,还是说需要先pull拉取远程的内容,然后才能 push?
由于远程的other_branch分支比较新,比本地库多一下内容: my_other_branch.txt如下
本地other_branch分支
此时,我在本地库中创建了other_branch_push_test.txt想把这个文件,想把这个变化直接推送到远程库dev分支,可以吗,还是说要先pull? 注意此时远程库dev分支比本地库dev分支要新
答案是:不可以!!!
可以通过上图看到,我尝试直接将本地other_branch分支直接推送到远端库的other_branch分支,直接报错。看了提示后:push更新操作之所以会被reject,主要是因为远程库中包含一些本地所不具有的内容。之所以造成远程库other_branch分支比本地库other_branch分支新这现象,主要是因为有其他人(比如你的工作伙伴)比你先提交了一下东西上去了,所以你需要先将远程的新内容拉取pull到本地,然后才能push。
所以我们先需要执行以下命令将远程other_brach拉取并合并到本地other_branch分支,然后才能push本地新增的内容。
git pull origin other_branch:other_branch。
git push origin other_branch:other_branch
(2)、本地other_branch分支中修改了文件,但没有git add也没有git commit的内容,会不会push到远程库other_branch分支中?有git add 但是没有git commit的内容会不会push到远程库other_branch 分支?
答案:不会!!!
没有git add也没有commit的内容,是不会推送到远程库中的。
仅仅git add 没有commit的内容,也不会推送到远程库中。
只有git add 同时也commit的内容,才会被推送到远程库中。
git merge用来合并两个分支
首先我们在master分支和other_branch 分支同时都创建一个merge_test.txt文件,并都添加相同的一句话:hello world
在other_branch分支上创建merge_test.txt文件并添加内容
在master分支上创建爱你merge_test文件并添加内容
在master上merge合并other_branch分支
并没有产生冲突,为什么??
主要是因为,master分支和other_branch两个分支的merge_test.txt的内容完全相同,可以直接将other_branch分支合并到master分支上。
接下来,修改master分支的merge_test.txt文件,但在第二行添加”11111111”内容修改other_branch分支的merge_test.txt文件,在第二行添加”22222222”内容,然后合并两个分支看是否会发生冲突。
修改master分支
修改other_branch分支
在不同分支上,修改merge_test.txt同一个文件同一个位置添加不同内容,是否会产生冲突
答案:会!!!
查看master分支上的merge_test.txt
此时想看一下other_branch分支的内容,结果失败,冲突解决之前不允许切换分支
对同一个文件的同一行,添加不同的内容,当然会造成冲突,merge_test.txt的第二行内容到底以谁为准,还是说你有新的想法,必须要解决这个问题。
这里你自己看着办,编辑master分支的merge_test.txt文件,修改第二行内容,综合考虑两家的意见后,决定将master分支添加的“1111111”和other_branch“22222222”都纳入到merge_test.txt的第二行内容。如下
将修改提交后,冲突就解决了,注意到主分支状态由(master|MERGING)变成(master)。现在就可以切换分支了。
# 在当前目录新建一个Git代码库
$ git init
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]
# 下载一个项目和它的整个代码历史
$ git clone [url]
# 显示当前的Git配置
$ git config --list
# 编辑Git配置文件
$ git config -e [--global]
# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"
# 添加指定文件到暂存区
$ git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录
$ git add [dir]
# 添加当前目录的所有文件到暂存区
$ git add .
# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p
# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...
# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]
# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]
# 提交暂存区到仓库区
$ git commit -m [message]
# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]
# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a
# 提交时显示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]
# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...
# 列出所有本地分支
$ git branch
# 列出所有远程分支
$ git branch -r
# 列出所有本地分支和远程分支
$ git branch -a
# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
# 新建一个分支,并切换到该分支
$ git checkout -b [branch]
# 新建一个分支,指向指定commit
$ git branch [branch] [commit]
# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
# 切换到上一个分支
$ git checkout -
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
# 合并指定分支到当前分支
$ git merge [branch]
# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]
# 删除分支
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
# 列出所有tag
$ git tag
# 新建一个tag在当前commit
$ git tag [tag]
# 新建一个tag在指定commit
$ git tag [tag] [commit]
# 删除本地tag
$ git tag -d [tag]
# 删除远程tag
$ git push origin :refs/tags/[tagName]
# 查看tag信息
$ git show [tag]
# 提交指定tag
$ git push [remote] [tag]
# 提交所有tag
$ git push [remote] --tags
# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]
# 显示有变更的文件
$ git status
# 显示当前分支的版本历史
$ git log
# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat
# 搜索提交历史,根据关键词
$ git log -S [keyword]
# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s
# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature
# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]
# 显示指定文件相关的每一次diff
$ git log -p [file]
# 显示过去5次提交
$ git log -5 --pretty --oneline
# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]
# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
# 下载远程仓库的所有变动
$ git fetch [remote]
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ git remote show [remote]
# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]
# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]
# 上传本地指定分支到远程仓库
$ git push [remote] [branch]
# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force
# 推送所有分支到远程仓库
$ git push [remote] --all
# 恢复暂存区的指定文件到工作区
$ git checkout [file]
# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit] [file]
# 恢复暂存区的所有文件到工作区
$ git checkout .
# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]
# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard
# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]
# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]
# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]
# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]
# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop