Git~从入门到入坑。

Git~从入门到入坑。


文章目录


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 并没有发生变化,需要

  1. 切换到 master 分支。
geek@geek-PC:~/geek/git_demo$ git checkout master
Switched to branch 'master'
  1. 合并。

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$ 

  1. 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


给开源项目供献代码。

  • fork 源代码。(拿别人的代码进行二次开发)。

将别人的源代码拷贝到我个人的远程仓库。

  • 在自己仓库进行修改代码。

以前的流程(git clone…)。

  • 给源代码作者提交修复 bug 的申请(pull request)。


配置文件。

  • 项目配置文件。(./.git/config)。
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
  • 全局配置文件。(~/.gitconfig)。
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)。

/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 免密登录。

  • URL 中体现。

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
// 此时就不需要再输账号密码。

  • 通过 SSH。

[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 自动管理凭证。

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。

百科。
对项目的介绍。

发布了47 篇原创文章 · 获赞 1 · 访问量 1165

猜你喜欢

转载自blog.csdn.net/lyfGeek/article/details/104712766