#创建新文件夹
mkdir xxx
#进入
cd xxx
#初始化Git仓库
git init
#克隆远程仓库到本地,这种方式并没有与远程仓库进行关联
git clone 远程仓库ssh/http
# 克隆远程指定分支内容
git clone -b 【分支名称】 远程仓库ssh/http
#本地git仓库关联远程仓库
git remote add [远程仓库名称] [远程仓库ssh/http]
在从远程的仓库中clone代码的时候
可以不执行git init
的操作,直接执行git clone http://xxxxxxx就可以了,在clone的时候,会自动的初始化本地git仓库,同时clone远程仓库中设置的默认分支
的代码;如果不知道远程分支的名称,可以执行完clone以后使用git-bash
进入到刚才clone项目目录下,就会自动显示本地的分支名称,而这个分支名称就是与远程分支同名的。
当执行完
git init
以后,此时git-bash
中虽然显示一个当前所处的分支为master
,但是此时执行git branch 【新分支】
创建新的分支时,报fatal: Not a valid object name: ‘master’.
的错误,因为此时并未真正的建立任何分支,包含master分支
,只有当你执行git add .
和git commit -m 注释
以后,master
分支才真正的建立!
如何一次clone多个项目,可以写多个
git clone -b 【分支名称】 远程仓库ssh/http
命令,中间用分号(;)
隔开即可,如:git clone -b 【分支名称】 远程仓库ssh/httpA;git clone -b 【分支名称】 远程仓库ssh/httpB
如何一次clone多个分支
先执行git clone -b 【分支名称】 远程仓库ssh/http
,然后进入到项目的目录下,执行git checkout -b [想clone的另一个分支,如:dev] [远程分支名称,如:origin/dev]
,如果不知道远程分支名称,可以执行git branch -a
来查看。
当本地未使用git管理的项目需要推到远程后建立的分支时,可以在本地项目文件夹下使用如下方式:
git init # 初始化本地git仓库
git remote add [远程仓库名称] [远程仓库ssh/http] #本地git仓库关联远程仓库
git add . # 添加项目变动到暂存区
git commit -m 'message' # 提交代码到本地分支
# 接下来可以通过在master分支提交到远程或者新建一个分支来提交,这里新建一个分支
git checkout -b [新分支,如:dev] # 创建并切换到dev分支
git push origin dev # 提交代码到到远程
提交代码到远程仓库:
#首先进入到本地仓库文件夹
git add . #跟踪文件,可以是执行某一个文件或者本地仓库中的所有文件
git commit -m '代码变动说明'
git status #查看当前的状态
git push [远程仓库主机名称] [对应的分支名称]
合并自己的分支到主分支:
# 方法1直接merge
git checkout master #如果子子分支,先切换分支到主分支
git merge [子分支的名称]
# 在merge过程中如果出现冲突(使用【git status】命令查看冲突的位置),可以先解决冲突,解决完冲突,执行命令【git add .】,然后直接执行git commit,不填写commit message信息,merge操作就会继续执行
#最后再push本地仓库主分支到远程主分支即可
git push [远程仓库主机名称] master
# 方法2 先进行rebase在进行merge
git checkout [自己的分支]
git rebase master
git checkout master
git merge [自己的分支]
git push [远程仓库主机名称] master
# 方法2执行后log的graph为一条直线,而方法1在合并时会多出来一个合并的commit节点,
# 参考:https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
解决冲突后,执行完git add .
命令之后,使用git commit
命令进行合并代码,但是不写commit message
时,会报如下的信息:
...
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# please enter the commit message for your changes. Lines starting
# with `#` will be ignored,and an empty message aborts the commit.
...
这是因为在commit的时候没有写commit message
的原因, 解决方法:
- 在执行
git commit
时使用命令git commit -m 'commit message'
命令替换, - 在上述页面上的
#
号之后补充一些commit message
信息;然后点击esc
,输入:wq
,关闭页面 - 不输入任何内容,点击
esc
,输入:q
,关闭页面,这时使用的为默认的merge备注信息作为commit message
。
可以参考官方文档:git文档——分支的新建与合并
# cherry-pick的使用
# 如果项目中只需要将部分的代码合并到某一个分支上,则可以使用cherry-pick
# 加入当前有两个分支A和B,将A分支中的commitId=fffggg(非最新提交)合并到分支B上
# 1) 先切换到分支B
git checkout B
# 2) 执行cherry-pick的操作,将分支A中fffggg时的提交合并到分支B上
git cherry-pick fffggg
# 如果遇到冲突,先解决冲突,解决完冲突以后可以直接执行 git cherry-pick --continue
# 如何选择一个范围内的commit到当前的分支
git cherry-pick [startCommitId]..[endCommitId] # 当前命令不包含startCommitId,但是包含endCommitId
git cherry-pick [startCommitId]^..[endCommitId] # 当前命令既包含startCommitId,亦包含endCommitId
# 在执行的过程中,遇到冲突可以进行解决,解决以后,可以执行git add . 命令,然后执行git cherry-pick --continue继续进行pick操作即可
# git cherry-pick还有另外两个操作命令
git cherry-pick --abort # 终止cherry-pick操作,文件目录回到pick之前的状态
git cherry-pick --quit # 终止cherry-pick操作,但是文件目录中会记录已经pick的内容
选择一个commit范围内的代码到当前分支
添加本地文件到远程仓库:
# 首先建好远程的仓库
# 先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库
git init
#把文件添加到版本库中,添加所有的修改到暂存库(存储区)等待commit
git add .
#介绍另外一个常用的命令:git diff [options]
# [options]为可选参数,有两个选择:
# 1、--staged/--cached:用于展示已经添加到暂存区中的修改
# 2、不使用参数:添加修改到暂存区以后,文件又更新了哪些部分
# 如果已经添加到暂存区的文件再次被修改可以使用【git add <再次被修改的file>】命令将修改追加到暂存区
#用命令 git commit告诉Git,把文件提交到仓库
git commit -m "提交说明"
# 关联远程仓库
git remote add [远程仓库主机名称] [你的远程库地址]
#获取远程库与本地同步合并
# 方式一
git pull --rebase [远程仓库主机名称 origin] [远程仓库分支名称master]
# 方式二
git fetch [远程仓库主机名称 origin] [远程仓库分支名称,如:master]
# 执行完fetch以后,本地并不会自动出现一个可编辑的备份,而是出现一个指针,如:branch master -> FETCH_HEAD
# 合并到当前所在的分支上
git merge [fetch后的指针,如:FETCH_HEAD]
# 合并到本地某一个分支上
git checkout -b [本地分支名称(不存在则新建),如:dev] [fetch后的指针,如:FETCH_HEAD]
#把本地库的内容推送到远程,加了参数-u后,以后即可直接用git push 代替git push origin master
git push -u [远程仓库主机名称] [远程仓库分支名称]
# clone本地的仓库到另一个本地仓库
# eg:克隆本地A仓库到本地B仓库,B仓库不能已经在文件目录上创建,不然会克隆失败
git clone d:/ARepository d:/BRepository
rebase与merge是两个主要的进行分支合并的方法,rebase的方式可以将代码的commit使用一条直线来呈现,方便于查看历史提交的变化,但是rebase的使用要遵循一个"黄金法则"——不要在公共的分支上进行rebase的操作,这里的公共的分支我理解就是远程的大家均需要合并代码到其上的分支【例如开发时的远程的origin/develop分支】;
当我们在本地的develop分支上开发完以后,提交代码到远程时,如果这是已经有其他人提交了代码到origin/develop分支上时,这是我们可以执行上述的git pull --rebase …命令,这样就不会出现像merge时一样多出来一个关于合并相关的commit信息;
推荐博文:
1、Rebase
2、Git Rebase 黄金法则问题
git pull 命令:
- git pull 命令用于从远程获取代码并合并本地的版本;
- git pull 其实就是
git fetch
和git merge FETCH_HEAD
的简写- 命令格式:
git pull <远程主机名> <远程分支名>:<本地分支名>
;<本地分支名>
可以省略,如果省略代表将远程分支合并到当前的分支
切换远程仓库地址
切换远程仓库的命令如下:
# 修改远程仓库地址
git remote set-url <远程仓库主机名称 origin> <新地址 newurl>
# 其他常用命令:
# 查看远程仓库信息
git remote -v
# 查看指定远程仓库信息
git remote show <远程仓库主机名称 origin>
配置仓库的用户名及邮箱
配置全局邮箱、用户名和单个仓库的邮箱和用户名:
# 配置全局
git config --global user.name "用户名"
git config --global user.email "邮箱"
git config --list # 查看配置列表
# 配置单个仓库
git config user.name "用户名"
git config user.email "邮箱"
git config --list # 当前项目下查看为全局的配置加上当前的配置
tag相关操作
git打tag相关操作:
git tag # 查看所有的标签
git tag <tag name> # tag在最新提交的commit
git tag <tag name> <commitID> # 在某个commit上打tag
git tag <tag name> -m 'message' # 打tag时添加附注信息
git tag -d <tag name> # 删除本地仓库中的tag
git push <远程仓库主机名称 origin> :refs/tags/<tag name> # 本地tag删除了,在执行该句,删除远程tag
git push <远程仓库主机名称 origin> <tag name> # 推送一个标签到远程
git push <远程仓库主机名称 origin> --tags # 推送全部未推送的本地标签
git fetch <远程仓库主机名称 origin> tag <版本名称> # 获取主机上指定的tag,当在主机上打了tag以后,可以通过该命令将tag获取到本地
撤销与回滚操作
撤销操作
# 1、在工作目录中做了修改,但是还没有执行 git add,撤销到上一次提交的状态
git checkout -f -- [filename,指定撤销文件] # 撤销指定文件
git checkout -f -- . # 撤销所有的文件
# 2、在工作目录中做了修改,并且已经 git add,但还没 git commit,执行以下两步操作:
# 第一步:先将暂存区的修改撤销,此时修改只存在于工作区,变为了 "unstaged changes";
git reset HEAD [filename,指定撤销文件] # 撤销暂存区中的指定文件
git reset HEAD # 撤销暂存区中所有的文件
#第二步:再利用上面1中的checkout命令从工作区撤销修改
# 3、在工作目录中做了修改,并且已经 git add 和 git commit
git reset --hard [HEAD^/commitid,上一个版本/指定commitid] # 回退到上一个版本/指定commitid,清除暂存区和工作目录
git revert <commitid,提交id> # 撤销任意一次的提交commitid1,但是commitid1之后的提交仍然存在;
reset
与revert
的区别
git reset
的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本,如下图所示,假设我们要回退到版本一:
适用场景: 如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法。
git revert
是用于“反做”某一个版本,以达到撤销该版本的修改的目的;
例如,已经commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:
适用场景: 如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。
此部分来源于参考博客:Git恢复之前版本的两种方法reset、revert(图文详解)
git reset
命令的使用
接下来介绍下
git reset [options] [parameter]
命令的使用:
1、git reset
相当于git reset --mixed
可以撤销掉git add .
的操作;
2、options 可以有三个选择:
--mixed
:默认值,可以不用带该参数,用于【重置暂存区的文件】与上一次的提交(commit)保持一致,【工作区文件内容保持不变】;【用于取消暂存区中的内容,也可以使用命令git reset HEAD <file>
来取消暂存区中的特定文件】--soft
:执行以后保留文件目录中的内容,同时会把保留文件目录所带来的的差异放入到存储区,相当于只执行了git add .
--hard
:执行以后暂存区(staged)和文件目录中的修改都会被清除掉。
# git reset使用举例:
git reset [--hard 可选] HEAD^ 回退到上个版本
git reset [--hard 可选] HEAD~3 回退到前3次提交之前,以此类推,回退到n次提交之前
git reset [--hard 可选] commit_id 退到/进到 指定commit的sha码
撤销reset的操作
## 执行reset命令后如果后悔了可以按照如下的步骤进行操作
1、git reflog # 先查询操作commit,reflog与log的区别在于reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)
2、git reset 【options】 HEAD@{n} # 找到reset之前的记录进行回退即可,其中n为对应的记录编号
git reflog查询到的日志形式为:
历史commit查看
git 查看commit树:
# 查看某一个分支的历史记录
git log [分支名称,可选,默认当前分支] --graph [options..]
# options部分内容如下所示:
# --pretty=oneline: 可选,让commit信息在一行上展示
# --decorate:可选,显示commit的引用信息(如:分支、tag等信息)
# 查看某一个文件的历史记录
git log --pretty=oneline <文件名> # git log --pretty=oneline sql/aa.sql 查看sql文件夹下aa.sql的历史记录
# 查看某一个问价某一次提交的详细信息
# 1、先执行上述的git log --pretty=oneline <文件名> 命令获取commitId
# 2、执行下面所示的git 命令
git show <commitId> <文件名>
冲突解决
当合并分支遇到冲突时先执行git status
命令,查看冲突的文件,显示如下内容:
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
然后进入到冲突的文件中,进行修改:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
======= 的上半部分指示当前分支(master),以下部分指示要合并的分支
解决完冲突以后,对每个文件使用 git add
命令来将其标记为冲突已解决, 你可以再次运行 git status
来确认所有的合并冲突都已被解决:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
如果你对结果感到满意,并且确定之前有冲突的的文件都已经暂存了,这时你可以输入 git commit
来完成合并提交(也可以使用git commit -m ''
来自定义message)。 默认情况下提交信息看起来像下面这个样子:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
至此,冲突解决完毕并提交。
其他问题解决
问题描述:
【Git】合并分支出现 Please enter a commit message to explain why this merge is necessary.
解决办法:
不写原因直接3,4步骤,写原因则1,2,3,4步骤
1. 按键盘字母 i 进入insert模式
2. 修改最上面那行黄色合并信息,可以不修改
3. 按键盘左上角"Esc"
4. 输入":wq",注意是冒号+wq,按回车键即可
Tips:
- 删除分支的命令有
git branch -d <branchname>
和git branch -D <branchname>
,其中-D
表示强制删除;本地分支在没有合并到其他分支,且没有对应的远程分支时。
参考博客:https://blog.csdn.net/qq_42072311/article/details/80696886