Git~从入门到入坑。
文章目录
- Git~从入门到入坑。
- Git 发展。
- 安装。
- 使用。
- Git 命令总结图。
- 分支。
- Git 工作流。
- GitHub。
- PULL。
- 小结。
- 在公司忘记 push 代码,咋办。
- 命令总结图。
- rebase(变基)——使 git 记录更简洁。
- beyond compare(软件)快速解决冲突。
- 命令小结。
- GitFlow。
- 多人协同开发。
- 给开源项目供献代码。
- 配置文件。
- Git 免密登录。
- Git 忽略文件。(.ignore)。
- 任务管理相关。
Git 发展。
安装。
https://git-scm.com/
使用。
git init 命令和 .git 目录。
-
进入要管理的文件夹。(cd)
-
初始化。(git init)。
使用了
git init
命令后,会在当前目录生成一个.git
文件夹。
我们在使用git ...
命令操作的记录会存储在这个文件夹中。
如果是一个新的目录,没有使用过 git init
命令,当前目录下则没有 .git
目录,git
命令就对当前文件夹无效。
geek@geek-PC:~/geek/git_demo/git_home$ git status
fatal: Not a git repository (or any of the parent directories): .git
此时需要使用 git init
命令将当前目录交由 git 接管。
geek@geek-PC:~/geek/git_demo/git_home$ git init
Initialized empty Git repository in /home/geek/geek/git_demo/git_home/.git/
geek@geek-PC:~/geek/git_demo/git_home$ ls -a
. .. .git
// 出现 .git 目录。
.git 目录下会存储 git 的版本信息。
即,我们每次使用 git 的命令(eg. git add, git commit…)所产生的记录都会记录其中。这也是为什么 git 可以记录我们的版本历史。
git status。
// 检测当前文件夹中文件的状态。
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
这里如果我们新建
了文件或修改
了文件,git 会自动检测到。
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
readme
nothing added to commit but untracked files present (use "git add" to track)
git add …
// 将文件加入暂存区。
使用
git add .
或git add *
命令将所有新增文件或已修改文件加入到暂存区
,或只添加指定文件git add [文件名]
。
git add [文件名]
git add . # 添加所有。
git add * # 添加所有。
geek@geek-PC:~/geek/git_demo/git_home$ git add readme
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: readme
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html
geek@geek-PC:~/geek/git_demo/git_home$
git commit …
// 将暂存区中的文件提交至本地版本库。
git commit -m “”
“” 中填写本次提交的原因(备注),以便以后查看版本历史可以知道这个版本做过什么。
至此,这个文件夹中的文件已经让 git 生成了一个版本。
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "new_geek。"
[master (root-commit) b7c5f61] new_geek。
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 index.html
create mode 100644 readme
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
nothing to commit, working tree clean
- 修改文件、修改代码。
如果被提交的文件在本地发生了变化(被修改),git 就会自动检测到。
使用git status
查看当前 git 的状态。
geek@geek-PC:~/geek/git_demo/git_home$ vim index.html
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
这时需要重新 git add ...
并 git commit -m "..."
。
geek@geek-PC:~/geek/git_demo/git_home$ git add .
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "v2"
[master 04be16a] v2
1 file changed, 1 insertion(+)
git log。
前面提到过,我们在 git 中所有操作都会保存到 .git
文件夹中。
可以通过 git log
查看历史版本信息。
此时就生成了两个版本。
geek@geek-PC:~/geek/git_demo/git_home$ git log
commit 04be16a1230e17a6f3325ab1f8940f993f33e80a
Author: geek <[email protected]>
Date: Mon Mar 9 16:50:23 2020 +0800
v2
commit b7c5f61d6ae65302ffc00f79fa3b364d6a1a3b24
Author: geek <[email protected]>
Date: Mon Mar 9 16:45:46 2020 +0800
new_geek。
geek@geek-PC:~/geek/git_demo/git_home$
小结。
回滚。
git reset --hard [版本号]
- 回滚到之前版本状态。
git reset --hard [版本号]
04be16a1230e17a6f3325ab1f8940f993f33e80a
geek@geek-PC:~/geek/git_demo/git_home$ git log
commit 918c368a60cffd9b57acf47b67f0944817545305
Author: geek <[email protected]>
Date: Mon Mar 9 16:57:01 2020 +0800
v3
commit 04be16a1230e17a6f3325ab1f8940f993f33e80a
Author: geek <[email protected]>
Date: Mon Mar 9 16:50:23 2020 +0800
v2
commit b7c5f61d6ae65302ffc00f79fa3b364d6a1a3b24
Author: geek <[email protected]>
Date: Mon Mar 9 16:45:46 2020 +0800
:
使用 git reset --hard [版本号]
回滚后,v3 版本用 git log
命令找不到了。
geek@geek-PC:~/geek/git_demo/git_home$ git reset --hard 04be16a1230e17a6f3325ab1f8940f993f33e80a
HEAD is now at 04be16a v2
geek@geek-PC:~/geek/git_demo/git_home$ git log
commit 04be16a1230e17a6f3325ab1f8940f993f33e80a
Author: geek <[email protected]>
Date: Mon Mar 9 16:50:23 2020 +0800
v2
commit b7c5f61d6ae65302ffc00f79fa3b364d6a1a3b24
Author: geek <[email protected]>
Date: Mon Mar 9 16:45:46 2020 +0800
new_geek。
只有 v1 和 v2 了。
此时要用 git reflog
命令查看全部版本历史(包括回滚历史)。
geek@geek-PC:~/geek/git_demo/git_home$ git reflog
04be16a HEAD@{0}: reset: moving to 04be16a1230e17a6f3325ab1f8940f993f33e80a
918c368 HEAD@{1}: commit: v3
04be16a HEAD@{2}: commit: v2
b7c5f61 HEAD@{3}: commit (initial): new_geek。
同样使用 git reset --haed 版本号
。
geek@geek-PC:~/geek/git_demo/git_home$ git reset --hard 918c368
HEAD is now at 918c368 v3
小结。
Git 命令总结图。
分支。
一般来说,开启新分支的作用就是
- 对之前代码的改进。
- 增加新功能。
紧急修复 bug 解决方案。
查看所有分支。
git branch
geek@geek-PC:~/geek/git_demo/git_home$ git branch
* master
创建分支。
git branch [分支名]
*
表示当前分支。
geek@geek-PC:~/geek/git_demo/git_home$ git branch dev
geek@geek-PC:~/geek/git_demo/git_home$ git branch
dev
* master
// 一般,dev 表示 develop,开发,用于开发新功能。
切换分支。
git branch [分支名]
geek@geek-PC:~/geek/git_demo/git_home$ git checkout dev
Switched to branch 'dev'
现在,假设我们在 bug 分支修改 bug。
geek@geek-PC:~/geek/git_demo$ git status
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch bug
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
geek@geek-PC:~/geek/git_demo/git_home$ git commit -a -m "modify bugs."
[bug 7d2ea98] modify bugs.
1 file changed, 2 insertions(+)
现假设我们在 bug 分支修改了bug,却忘记了 add 和 commit。
geek@geek-PC:~/geek/git_demo/git_home$ touch bug.txt
geek@geek-PC:~/geek/git_demo/git_home$ ls
bug.txt index.html readme
合并。
之前在其他分支修改了代码,当我们切回主分支 master
,主分支 master
并没有发生变化,需要
- 切换到 master 分支。
geek@geek-PC:~/geek/git_demo$ git checkout master
Switched to branch 'master'
- 合并。
git merge bug
// 使用 git merge bug
(git merge + 分支名)。
合并之后就可以把另一分支的修改合并到当前分支。
geek@geek-PC:~/geek/git_demo/git_home$ git checkout master
Switched to branch 'master'
geek@geek-PC:~/geek/git_demo/git_home$ ls
index.html readme
geek@geek-PC:~/geek/git_demo/git_home$ git merge bug
Updating 7d2ea98..02dfbca
Fast-forward
bug.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bug.txt
geek@geek-PC:~/geek/git_demo/git_home$ ls
bug.txt index.html readme
删除分支。
git branch -d bug
// 确保修复的 bug 已经被合并到主分支,就可以删除多余的分支。
geek@geek-PC:~/geek/git_demo/git_home$ git branch
bug
dev
* master
geek@geek-PC:~/geek/git_demo/git_home$ git branch -d bug
Deleted branch bug (was 02dfbca).
geek@geek-PC:~/geek/git_demo/git_home$ git branch
dev
* master
分支冲突。
如果在两个分支修改了同一个文件,合并分支时会报出错。
在 master 分支做开发。
geek@geek-PC:~/geek/git_demo/git_home$ git branch
dev
* master
geek@geek-PC:~/geek/git_demo/git_home$ ls
bug.txt index.html readme
geek@geek-PC:~/geek/git_demo/git_home$ vim index.html
geek@geek-PC:~/geek/git_demo/git_home$ git add .
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "after bug."
[master cb256a2] after bug.
1 file changed, 2 insertions(+)
在 dev 分支做开发。
geek@geek-PC:~/geek/git_demo/git_home$ git checkout dev
Switched to branch 'dev'
geek@geek-PC:~/geek/git_demo/git_home$ ls
index.html readme
geek@geek-PC:~/geek/git_demo/git_home$ vim index.html
geek@geek-PC:~/geek/git_demo/git_home$ git add .
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "after bug. dev."
[dev 7a19128] after bug. dev.
1 file changed, 2 insertions(+)
在 master 分支合并 dev。
geek@geek-PC:~/geek/git_demo/git_home$ git merge dev
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
有冲突,自动合并失败。
打开文件可以看到(冲突,conflict)。
只能手动解决。
<<<<<<< HEAD
bug
after bug -> dev
=======
idev
>>>>>>> dev
手动打开文件,删除不需要的代码,保存。
geek@geek-PC:~/geek/git_demo$ git status
geek@geek-PC:~/geek/git_demo/git_home$ vim index.html
geek@geek-PC:~/geek/git_demo/git_home$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
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")
geek@geek-PC:~/geek/git_demo/git_home$ git add .
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "confilct ok."
[master 4c2ad59] confilct ok.
命令小结。
- 查看所有分支。
git branch
- 创建分支。
git branch 分支名
- 切换分支。
git checkout 分支名
- 分支合并。
git merge 分支名
进入主分支(想要合并到的分支),使用 git merge + 要合并的分支。
可能产生冲突。—> 手动编辑(删除)冲突。
- 删除分支。
git branch -d 分支名
Git 工作流。
GitHub。
至此,以上操作都是在一台电脑中的操作。如果我们要在不同地点做开发(eg. 家里和公司两地),又想使开发进度同步,就需要一个“中转站”。
GitHub 是一个面向开源及私有软件项目的托管平台,因为只支持 git 作为唯一的版本库格式进行托管,故名 GitHub。
gitlab —> 自己搭仓库服务器。
注册账号。
创建仓库。
- 本地代码推送到 GitHub。
Add a License —> 限制商用。
创建好以后,仓库主页出现如下提示。
…or create a new repository on the command line
echo "# git_demo" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/lyfGeek/git_demo.git
git push -u origin master
…or push an existing repository from the command line
git remote add origin https://github.com/lyfGeek/git_demo.git
git push -u origin master
…or import code from another repository
You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
操作。我们要将自己电脑本地的代码上传到 GitHub。
将本地的 git 版本库和 GitHub 上的仓库绑定。
git remote add origin https://github.com/lyfGeek/git_demo.git
// 将本地的 git 版本库和 GitHub 上的仓库绑定。
// 在本地给https://github.com/lyfGeek/git_demo.git
起别名origin
。
geek@geek-PC:~/geek/git_demo/git_home$ git remote add origin https://github.com/lyfGeek/git_geek.git
# origin(别名)指向 ——> https://github.com/lyfGeek/git_demo.git
推送。
第一次需要输入 GitHub 的账号密码。
geek@geek-PC:~/geek/git_demo/git_home$ git push -u origin master
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
Counting objects: 23, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (23/23), 1.98 KiB | 0 bytes/s, done.
Total 23 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/lyfGeek/git_geek.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
-u —> 参数。设置默认
push
的路径。
下一次使用push
就可以不再指定路径(如果你还是想上传到这个仓库)。不然可以再次指定路径git push origin xxx
。
提交成功,并且所有版本记录都会被一并提交。
但推送到 GitHub 的分支只有 master
,dev 分支需要另外推送。
geek@geek-PC:~/geek/git_demo/git_home$ git push origin dev
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'dev' on GitHub by visiting:
remote: https://github.com/lyfGeek/git_geek/pull/new/dev
remote:
To https://github.com/lyfGeek/git_geek.git
* [new branch] dev -> dev
Clone。
以上都是在同一台电脑上的操作。假设我们现在要去公司,并且要同步在家中的开发进度。就要把 GitHub 上的代码 clone
至公司的电脑中。
geek@geek-PC:~/geek/git_demo$ mkdir git_clone
geek@geek-PC:~/geek/git_demo$ cd git_clone/
geek@geek-PC:~/geek/git_demo/git_clone$ git clone https://github.com/lyfGeek/git_geek.git
Cloning into 'git_geek'...
remote: Enumerating objects: 23, done.
remote: Counting objects: 100% (23/23), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 23 (delta 1), reused 23 (delta 1), pack-reused 0
Unpacking objects: 100% (23/23), done.
geek@geek-PC:~/geek/git_demo/git_clone$ ls
git_geek
clone 完成后,进入目录。
geek@geek-PC:~/geek/git_demo/git_clone$ cd git_geek/
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ ls
bug.txt index.html readme
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ ls -a
. .. bug.txt .git index.html readme
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git branch
* master
使用 git log
可以查看所有的记录。
查看分支,只有 master 一个。
geek@geek-PC:~/geek/git_demo/git_clone/git_demo$ git branch
* master
其实所有分支都在,只是没有显示。直接使用 git checkout dev
。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git checkout dev
Branch dev set up to track remote branch dev from origin.
Switched to a new branch 'dev'
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git branch
* dev
master
命令小结。
- 给远程仓库起别名。
git remote add origin 远程仓库地址
# origin 任意,只是起的别名。
- 向远程推送代码。
git push -u origin 分支
- 克隆远程仓库代码。
git clone 远程仓库地址
// 内部已经实现 ——>
git remote add origin 远程仓库地址
这里使用 git branch
只会显示 master
一个分支,以前原有的分支不显示。但可以直接使用 git checkout
+ 以前原有的分支名直接切换分支。
git checkout dev
此时 clone
下来的代码不是最新的,如图,dev 分支在 C7
,而主分支 merge
后,在 C8
了。
实际开发中,我们不知道,也不能确定主分支上是否合并过其他分支,所有不管当前分支(dev)是不是和 master
分支一样是最新的,都操作一遍:git merge master
。
一天代码写完了,下班前再提交一遍。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ touch a.py
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ vim a.py
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git add *
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git commit -m "day01."
[dev f3c9f6f] day01.
1 file changed, 1 insertion(+)
create mode 100644 a.py
推送。
git push -u origin dev
这里
-u
指的是第一次git push -u origin dev
便指定 push 到 origin 的 dev 分支。
以后再次提交可以直接git push
,使用默认,push 到 origin 的 dev 分支。
当然也可以git push origin dev
,手动指定。(不使用默认的了)。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ vim a.py
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git add *
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git commit -m "day01."
[dev f3c9f6f] day01.
1 file changed, 1 insertion(+)
create mode 100644 a.py
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git push origin dev
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 303 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/lyfGeek/git_geek.git
7a19128..f3c9f6f dev -> dev
TODO:每次都要输密账号码。
参考配置文件
。
PULL。
回到家后,代码还是没更新。(没有 a.py)。
geek@geek-PC:~/geek/git_demo$ cd git_home/
geek@geek-PC:~/geek/git_demo/git_home$ ls
bug.txt index.html readme
需要先更新(pull)一下。
geek@geek-PC:~/geek/git_demo/git_home$ git pull origin dev
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 2 (delta 1), reused 2 (delta 1), pack-reused 0
Unpacking objects: 100% (2/2), done.
From https://github.com/lyfGeek/git_geek
* branch dev -> FETCH_HEAD
f3c9f6f..3b69f16 dev -> origin/dev
Merge made by the 'recursive' strategy.
b.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 b.py
geek@geek-PC:~/geek/git_demo/git_home$ ls
a.py b.py bug.txt index.html readme
小结。
- 在家里上传代码。
给远程仓库起别名。
git remote add origin 远程仓库地址
向远程仓库推送代码。
git push -u origin 分支
- 到公司新电脑第一次获取 GitHub 上的代码。
克隆远程仓库代码。
git clone 远程仓库地址
(内部已实现 git remote add oringin 远程仓库地址)切换分支
git branch 分支
- 在公司进行开发。
切换到 dev 分支进行开发。
git checkout dev
把 master 分支合并到 dev。
git merge master
修改代码。
提交代码。git add .
git commit -m “xxx”
git push origin dev
- 回到家中继续撸代码。
切换到 dev 分支进行开发。
git checkout dev
拉代码。
git pull origin dev
继续开发。
提交代码。
git add .
git commit -m “xxx”
git push origin dev
- 在公司继续开发。
切换到 dev 分支进行开发。
git checkout dev
拉代码。
git pull origin dev
继续开发。
提交代码。git add .
git commit -m “xxx”
git push origin dev
开发完毕,要上线。
将 dev 分支合并到 master,准备上线。
git checkout master
git merge dev
git push origin master// 此时 dev 分支和 master 分支是一样的。将 dev 分支也推送。
git checkout dev
git merge master
git push origin dev
回到家中,也同步一下。
…
在公司忘记 push 代码,咋办。
先写其他功能。
这次别忘了 add, commit, push。
第二天到公司,合并。这时可能会有冲突。
在公司开发了一半,但忘记 push。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ vim a2.py
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git add .
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git commit -m "第 2 天在公司开发 的,但忘记 push。"
[dev 3499fad] 第 2 天在公司开发的,但忘记 push。
1 file changed, 1 insertion(+)
create mode 100644 a2.py
回到家中,pull,没有变化。
geek@geek-PC:~/geek/git_demo/git_home$ git pull
Already up-to-date.
在家继续开发其他功能。
geek@geek-PC:~/geek/git_demo/git_home$ git checkout dev
Switched to branch 'dev'
geek@geek-PC:~/geek/git_demo/git_home$ vim a2.py
geek@geek-PC:~/geek/git_demo/git_home$ git add .
geek@geek-PC:~/geek/git_demo/git_home$ git commit -m "在家开发了其他功能。"
[dev b1be27a] 在家开发了其他功能。
1 file changed, 1 insertion(+)
create mode 100644 a2.py
geek@geek-PC:~/geek/git_demo/git_home$ git push
fatal: The current branch dev has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin dev
geek@geek-PC:~/geek/git_demo/git_home$ git push origin dev
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 570 bytes | 0 bytes/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/lyfGeek/git_geek.git
3b69f16..de0a93f dev -> dev
到了公司,pull,产生冲突。手动解决。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ ls
a2.py a.py b.py index.html readme
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git pull
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 5 (delta 2), reused 5 (delta 2), pack-reused 0
Unpacking objects: 100% (5/5), done.
From https://github.com/lyfGeek/git_geek
3b69f16..de0a93f dev -> origin/dev
Auto-merging a2.py
CONFLICT (add/add): Merge conflict in a2.py
Automatic merge failed; fix conflicts and then commit the result.
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ ls
a2.py a.py b.py index.html readme
此时想切换至 master 分支,提示。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git checkout master
a2.py: needs merge
error: you need to resolve your current index first
先解决 conflict。
geek@geek-PC:~/geek/git_demo/git_clone/git_demo$ vim a2.py
geek@geek-PC:~/geek/git_demo/git_clone/git_demo$ git add .
geek@geek-PC:~/geek/git_demo/git_clone/git_demo$ git commit -m "合并之后并开发完毕。"
[dev 6327556] 合并之后并开发完毕。
geek@geek-PC:~/geek/git_demo/git_clone/git_demo$ git push origin dev
Username for 'https://github.com': [email protected]
Password for 'https://[email protected]@github.com':
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 726 bytes | 0 bytes/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/lyfGeek/git_demo.git
80d47fd..6327556 dev -> dev
解决了冲突就可以切换分支了。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git commit -m "解决了冲突。"
[dev e3e8ca6] 解决了冲突。
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git checkoutmaster
git: 'checkoutmaster' is not a git command. See 'git --help'.
geek@geek-PC:~/geek/git_demo/git_clone/git_geek$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
回到家中,pull。
命令总结图。
git pull origin dev
=
git fetch origin dev
git merge origin/dev
rebase(变基)——使 git 记录更简洁。
应用场景 1。
如图,如果一个任务 day 5 才完成,当把这个 git 记录给老板时,中间有大量多余的记录,老板并不关心。
geek@geek-PC:~/geek/git_demo$ mkdir git_rebase
geek@geek-PC:~/geek/git_demo$ ls
git_clone git_home git_rebase
geek@geek-PC:~/geek/git_demo$ cd git_rebase/
geek@geek-PC:~/geek/git_demo/git_rebase$ ls
geek@geek-PC:~/geek/git_demo/git_rebase$ git init
Initialized empty Git repository in /home/geek/geek/git_demo/git_rebase/.git/
geek@geek-PC:~/geek/git_demo/git_rebase$ touch 1.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "day 1"
[master (root-commit) 09a9ea5] day 1
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 1.py
geek@geek-PC:~/geek/git_demo/git_rebase$ touch 2.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "day 2"
[master 035042c] day 2
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 2.py
geek@geek-PC:~/geek/git_demo/git_rebase$ touch 3.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "day 3"
[master f85ea1b] day 3
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 3.py
geek@geek-PC:~/geek/git_demo/git_rebase$ touch 4.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add *
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "day 4"
[master 722f25a] day 4
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 4.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git log
commit 722f25ad09a1a989a173b2a72a6c9a4bf25ba1a4
Author: geek <[email protected]>
Date: Mon Mar 9 21:31:38 2020 +0800
day 4
commit f85ea1b2e29bd6cae0a2a6bd024b5603f6593a91
Author: geek <[email protected]>
Date: Mon Mar 9 21:31:12 2020 +0800
day 3
commit 035042cd38eb0acd275bac69128bf8d847ff7411
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:46 2020 +0800
day 2
commit 09a9ea5321265fa08a97c13c68545ac51b16873c
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:08 2020 +0800
day 1
geek@geek-PC:~/geek/git_demo/git_rebase$
- git rebase -i 035042cd38eb0acd275bac69128bf8d847ff7411
// 从当前到此版本号,中间合并。
git rebase -i HEAD~3
// 从当前开始,3 条记录合并。
geek@geek-PC:~/geek/git_demo/git_rebase$ git rebase -i HEAD~3
pick 035042c day 2
pick f85ea1b day 3
pick 722f25a day 4
# Rebase 09a9ea5..722f25a onto 09a9ea5 (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
pick 改变为 s。——> 当前行版本合并到上一行。
pick 035042c day 2
s f85ea1b day 3
s 722f25a day 4
保存后出现
# This is a combination of 3 commits.
# This is the 1st commit message:
day 2
# This is the commit message #2:
day 3
# This is the commit message #3:
day 4
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Mon Mar 9 21:30:46 2020 +0800
#
# interactive rebase in progress; onto 09a9ea5
# Last commands done (3 commands done):
# s f85ea1b day 3
# s 722f25a day 4
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on '09a9ea5'.
#
# Changes to be committed:
# new file: 2.py
# new file: 3.py
# new file: 4.py
#
# Untracked files:
# rebase_log
#
删去注释,将 v1, v2, v3 用 & 连接。保存。
day 2 & day 3 & day 4
geek@geek-PC:~/geek/git_demo/git_rebase$ git rebase -i HEAD~3
[detached HEAD c3b2fba] day 2
Date: Mon Mar 9 21:30:46 2020 +0800
3 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 2.py
create mode 100644 3.py
create mode 100644 4.py
Successfully rebased and updated refs/heads/master.
再次 git log
。
geek@geek-PC:~/geek/git_demo/git_rebase$ git log
commit c3b2fba70b81d2c580bc647434e35633c6c8d444
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:46 2020 +0800
day 2
day 3
day 4
commit 09a9ea5321265fa08a97c13c68545ac51b16873c
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:08 2020 +0800
day 1
如果版本已经 push,建议不要合并。
应用场景 2。
将 dev 分支插入 master 分支。
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout dev
Already on 'dev'
geek@geek-PC:~/geek/git_demo/git_rebase$ ls
1.py 2.py 3.py 4.py
geek@geek-PC:~/geek/git_demo/git_rebase$ touch dev.py
geek@geek-PC:~/geek/git_demo/git_rebase$ ls
1.py 2.py 3.py 4.py dev.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "dev."
[dev b267001] dev.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git log
commit b267001f1a556003f0ab6f7901cf7cac59350091
Author: geek <[email protected]>
Date: Mon Mar 9 22:13:39 2020 +0800
dev.
commit c3b2fba70b81d2c580bc647434e35633c6c8d444
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:46 2020 +0800
day 2
day 3
day 4
commit 09a9ea5321265fa08a97c13c68545ac51b16873c
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout master
Switched to branch 'master'
geek@geek-PC:~/geek/git_demo/git_rebase$ touch master.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "master 02."
[master 39ed08e] master 02.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git log
commit 39ed08e08a7908b18f99d1ec11ff8abe61ee03e6
Author: geek <[email protected]>
Date: Mon Mar 9 22:15:51 2020 +0800
master 02.
commit c3b2fba70b81d2c580bc647434e35633c6c8d444
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:46 2020 +0800
day 2
day 3
day 4
geek@geek-PC:~/geek/git_demo/git_rebase$
按照以前,git merge dev
即可。
geek@geek-PC:~/geek/git_demo/git_rebase$ git merge dev
Merge made by the 'recursive' strategy.
dev.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev.py
git log --graph
geek@geek-PC:~/geek/git_demo/git_rebase$ git log --graph
* commit ec5c71e6d5b56ba5676986e3d5dcb364d0b9088b
|\ Merge: 39ed08e b267001
| | Author: geek <[email protected]>
| | Date: Mon Mar 9 22:20:31 2020 +0800
| |
| | Merge branch 'dev'
| |
| * commit b267001f1a556003f0ab6f7901cf7cac59350091
| | Author: geek <[email protected]>
| | Date: Mon Mar 9 22:13:39 2020 +0800
| |
| | dev.
| |
* | commit 39ed08e08a7908b18f99d1ec11ff8abe61ee03e6
|/ Author: geek <[email protected]>
| Date: Mon Mar 9 22:15:51 2020 +0800
geek@geek-PC:~/geek/git_demo/git_rebase$ git log --graph
* commit ec5c71e6d5b56ba5676986e3d5dcb364d0b9088b
|\ Merge: 39ed08e b267001
| | Author: geek <[email protected]>
| | Date: Mon Mar 9 22:20:31 2020 +0800
| |
| | Merge branch 'dev'
| |
| * commit b267001f1a556003f0ab6f7901cf7cac59350091
| | Author: geek <[email protected]>
| | Date: Mon Mar 9 22:13:39 2020 +0800
| |
| | dev.
| |
* | commit 39ed08e08a7908b18f99d1ec11ff8abe61ee03e6
|/ Author: geek <[email protected]>
| Date: Mon Mar 9 22:15:51 2020 +0800
|
| master 02.
|
* commit c3b2fba70b81d2c580bc647434e35633c6c8d444
| Author: geek <[email protected]>
| Date: Mon Mar 9 21:30:46 2020 +0800
|
| day 2
|
| day 3
|
| day 4
|
* commit 09a9ea5321265fa08a97c13c68545ac51b16873c
Author: geek <[email protected]>
Date: Mon Mar 9 21:30:08 2020 +0800
day 1
git log --graph --pretty=format:"%h %s"
geek@geek-PC:~/geek/git_demo/git_rebase$ git log --graph --pretty=format:"%h %s"
* ec5c71e Merge branch 'dev'
|\
| * b267001 dev.
* | 39ed08e master 02.
|/
* c3b2fba day 2
* 09a9ea5 day 1
正式开始。
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout dev
Switched to branch 'dev'
geek@geek-PC:~/geek/git_demo/git_rebase$ git merge master
Updating b267001..ec5c71e
Fast-forward
master.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master.py
geek@geek-PC:~/geek/git_demo/git_rebase$ touch dev1.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "dev branch 01."
[dev 615f89c] dev branch 01.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev1.py
切回 master。
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout master
Switched to branch 'master'
geek@geek-PC:~/geek/git_demo/git_rebase$ touch master01.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "master 01."
[master 95145a2] master 01.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master01.py
和以前不同,现在不要 merge。
切回 dev。
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout dev
Switched to branch 'dev'
geek@geek-PC:~/geek/git_demo/git_rebase$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: dev branch 01.
再切回 master。
geek@geek-PC:~/geek/git_demo/git_rebase$ git checkout master
Switched to branch 'master'
geek@geek-PC:~/geek/git_demo/git_rebase$ git merge dev
Updating 95145a2..9c2e987
Fast-forward
dev1.py | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dev1.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git log --graph --pretty=format:"%h %s"
* 9c2e987 dev branch 01.
* 95145a2 master 01.
* ec5c71e Merge branch 'dev'
|\
| * b267001 dev.
* | 39ed08e master 02.
|/
* c3b2fba day 2
* 09a9ea5 day 1
应用场景 3。
如果 git rebase ...
产生冲突。
解决:… git add ...
…按照提示。。。
git rebase --continue
beyond compare(软件)快速解决冲突。
- 安装 Beyond Compare。
- 在 git 中配置。
–local ——> 仅在当前项目有效。
geek@geek-PC:~/geek/git_demo/git_rebase$ git config --local merge.tool bc3
geek@geek-PC:~/geek/git_demo/git_rebase$ git config --local mergetool.path "/usr/lib/beyondcompare"
geek@geek-PC:~/geek/git_demo/git_rebase$ git config --local mergetool.keepBackup false
geek@geek-PC:~/Downloads$ whereis beyondcompare
beyondcompare: /usr/lib/beyondcompare
演示开始。
geek@geek-PC:~/geek/git_demo/git_rebase$ git branch
dev
* master
geek@geek-PC:~/geek/git_demo/git_rebase$ vim conflict.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git add .
geek@geek-PC:~/geek/git_demo/git_rebase$ git commit -m "conflict_master."
[master 2173ba5] conflict_master.
1 file changed, 1 insertion(+)
create mode 100644 conflict.py
geek@geek-PC:~/geek/git_demo/git_rebase$ git mergetool
Merging:
conflict.py
Normal merge conflict for 'conflict.py':
{local}: created file
{remote}: created file
点击小箭头,选择应用哪个文件的内容,保存,关闭。即可。
geek@geek-PC:~/geek/git_demo/git_rebase$ git mergetool
Merging:
conflict.py
Normal merge conflict for 'conflict.py':
{local}: created file
{remote}: created file
命令小结。
- 添加远程链接。(取别名)。
git remote add origin 地址
- 推送代码。
git push origin dev
- 下载代码。
git clone 地址
- 拉取代码。
git pull origin dev
等价于
git fetch origin dev
git merge origin/dev
- 保持代码提交整洁(变基)。
git rebase 分支
- 记录图形展示。
git log --graph --pretty=format:"%h %s"
GitFlow。
工作流。
多人协同开发。
GitHub 中 new Repository。
在这个 Repository 中 Set up the organization。
一个组织中可以创建多个 Repositories。
一个公司中有多个组织,一个组织有多个项目。
标签。tag。
使用 tag
标签替代 hash 值。
在 GitHub 中也会自成对应的 Releases 版本,可供下载。
geek@geek-PC:~/geek/git_demo/git_flow$ touch first.py
geek@geek-PC:~/geek/git_demo/git_flow$ git add .
geek@geek-PC:~/geek/git_demo/git_flow$ git commit -m "first."
[master (root-commit) bf57457] first.
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 first.py
geek@geek-PC:~/geek/git_demo/git_flow$ git log
commit bf57457122da21bac53f6c7180bc29528ada71a2
Author: geek <[email protected]>
Date: Tue Mar 10 00:29:19 2020 +0800
first.
geek@geek-PC:~/geek/git_demo/git_flow$ git tag -a v1 -m "第一版。"
geek@geek-PC:~/geek/git_demo/git_flow$ git log
commit bf57457122da21bac53f6c7180bc29528ada71a2
Author: geek <[email protected]>
Date: Tue Mar 10 00:29:19 2020 +0800
first.
Boss 创建好基本工作,创建 dev 分支。
// 创建 dev 分支,并自动切换到 dev 分支。
geek@geek-PC:~/geek/git_demo/git_flow$ git checkout -b dev
Switched to a new branch 'dev'
geek@geek-PC:~/geek/git_demo/git_flow$ git branch
* dev
master
git push origin dev
小弟创建 GitHub 账号。Boss 拉人(从组织 invite someone)。
Boss 组织中为成员分配权限(或直接从项目给成员加权限)。
成员 clone。
从 dev 分支下(git checkout dev)创建新分支。
git checkout -d ddz
Boss, Review —> pull request(实现)。需要配置。
GitHub 中,
- Boss 账号配置。
Branches —> Branch protection rule。
// Require pull request reviews before merging.
// 想要和 dev 合并,必须先 review。
master 同样配置。
- 小弟账号。
Open a pull request.
填写申请。
- Boss 账号。
操作完可以删除分支。
进行测试。
Boss 从 dev 分支 git checkout -b release。
git push origin release。
master 中合并 release。
打标签。
git tag -a v2 -m “第二版 。。。”
git push origin --tags
给开源项目供献代码。
将别人的源代码拷贝到我个人的远程仓库。
以前的流程(git clone…)。
配置文件。
git config --local user.name "Geek"
git config --local user.email "[email protected]"
geek@geek-PC:~/geek/git_demo/git_flow$ ll .git
total 44
drwxr-xr-x 2 geek geek 4096 Mar 10 00:28 branches
-rw-r--r-- 1 geek geek 7 Mar 10 00:29 COMMIT_EDITMSG
-rw-r--r-- 1 geek geek 92 Mar 10 00:28 config
-rw-r--r-- 1 geek geek 73 Mar 10 00:28 description
-rw-r--r-- 1 geek geek 20 Mar 10 00:37 HEAD
drwxr-xr-x 2 geek geek 4096 Mar 10 00:28 hooks
-rw-r--r-- 1 geek geek 137 Mar 10 00:37 index
drwxr-xr-x 2 geek geek 4096 Mar 10 00:28 info
drwxr-xr-x 3 geek geek 4096 Mar 10 00:29 logs
drwxr-xr-x 8 geek geek 4096 Mar 10 00:30 objects
drwxr-xr-x 4 geek geek 4096 Mar 10 00:28 refs
geek@geek-PC:~/geek/git_demo/git_flow$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
geek@geek-PC:~/geek/git_demo/git_flow$ cat ~/.gitconfig
[user]
name = geek
email = [email protected]
git config --global user.name "Geek"
git config --global user.email "[email protected]"
/etc/.gitconfig
git config --system user.name "Geek"
git config --system user.email "[email protected]"
# 需要有 root 权限。
- 应用。
git config --local user.name "Geek"
git config --local user.email "[email protected]"
$ git config --local merge.tool bc3
$ git config --local mergetool.path "/usr/lib/beyondcompare"
$ git config --local mergetool.keepBackup false
git remote add origin 地址 # 默认添加在本地配置文件中(--local)。
Git 免密登录。
https://gitee.com/lyfGeek/git_geek.git
https://用户名:密码@gitee.com/lyfGeek/git_geek.git
~
git remote add origin https://用户名:密码@gitee.com/lyfGeek/git_geek.git
git push origin master
// 此时就不需要再输账号密码。
[email protected]:lyfGeek/git_geek.git
- 生成公钥私钥。(默认存在 ~/.ssh)。
ssh-keygen- geek@geek-PC:~$ ls .ssh/
id_rsa id_rsa.pub known_hosts- 将 id_rsa.pub 的公钥内容 copy 到 gitee 中。
- 在 git 本地中配置 ssh 地址。
git remote add origin [email protected]:lyfGeek/git_geek.git
~
以后使用。
git push origin master
Git 忽略文件。(.ignore)。
vim .gitignore
*.h
!a.h
.gitignore
target/
将需要忽略的文件加入 .ignore
文件中。
git 就不再管理。
! ——> 取反。
参考 https://github.com/github/gitignore
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
任务管理相关。
issues。
文档以及任务管理。
提交问题或 bug。
wiki。
百科。
对项目的介绍。