Git基础

介绍

技术 特性 适用场景 说明
Git 分布式版本控制 - 官网
- Doc
Gitflow 分支标准化管理 - Github
- 安装
- Gitflow Workflow Tutorials
Git LFS 大文件上传 Git Large File Storage (LFS) 是Github提供的大文件上传服务,可以用于Github上突破单个文件100M的限制。
官网
https://www.gitignore.io 在线生成.ignore文件

Git 客户端

Git 客户端 说明
Sourcetree
GitUp -

安装

CentOS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 卸载旧版本
$ yum remove git -y

# 安装依赖
$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
$ yum install gcc perl-ExtUtils-MakeMaker

# 下载最新版 git
$ wget https://github.com/git/git/archive/v2.9.2.tar.gz

# 解压
$ tar zxf git-2.9.2.tar.gz

# 安装
$ cd git-2.9.2
$ make prefix=/usr/local/git all
$ make prefix=/usr/local/git install

# 创建软链接
$ ln -s /usr/local/git/bin/git /bin/git

# 添加到环境变量
$ rm -rf /usr/bin/git
$ echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/bashrc
$ source /etc/bashrc


# 验证
$ git --version

基本概念

Git Flow

说明
master 分支 生产版本分支,要谨慎对待
develop 分支 开发分支
feature 分支 新特性分支,从 develop 创建。
每个新特性都需要开一个新分支。
release 分支 从 develop 创建
hotfix 分支 从 master 创建

Git 三个区

说明
本地区 历史版本
$ git commit
暂存区 临时存储
$ git add
工作区 写代码

基础命令

基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 创建数据库
$ git init

# 添加文件或目录到索引
## ".” :可以将子目录里的所有文件添加到索引
$ git add <filepattern>

# 提交追加到索引的文件
## -m:指令提交 “提交信息”
$ git commit

# 显示修改文件清单
$ git status

# 查看修改文件的差异
$ git diff

# 显示提交历史
## 若要查看特定文件的提交历史,请指定文件名称
## --graph:显示合并图
$ git log

# 查看提交的详细记录
$ git show <commit>

# 修改、移动文件的名称或目录的名称
$ git mv <oldfilename> <newfilename>

# 删除文件
$ git rm <file>

# 删除非管理对象的文件
$ git clean

# 还原正在手头上修改,还没被添加到索引里的文件
$ git checkout -- <file>

# 删除已添加到索引的文件
$ git reset HEAD -- <file>

# 只添加已提交过的文件到索引
$ git add -u

# 替换源
$ git remote set-url origin http://ip:port/xxx/xxx.git

# 删除 git 中某个文件夹
$ git rm -r --cached .mvn
$ git commit -m "删除了.mvn"
$ git push -u origin master

# 忽略已跟踪文件的变动
$ git update-index --assume-unchanged <file>
# 撤销忽略跟踪
$ git update-index --no-assume-unchanged <file>

# 忽略之前已提交文件
## 1. 首先删除本地缓存
$ git rm -r --cached .
## 2. 新建/修改 .gitignore 文件,将需要忽略的文件/文件夹路径写到 .gitignore 里
## 3. commit 本次变更
$ git commit -m "本次提交说明"
## 4. 推送到代码仓库
$ git push

分支操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看当前项目有哪些分支
## -a:显示包括远端分支在内的分支清单
$ git branch

# 创建分支
$ git branch <branchname>

# 修改分支的名称
$ git branch -m <oldbranch> <newbranch>

# 删除分支
$ git branch -d <branchname>

# 分支切换
## -b:新建分支和已建分支之间的切换
$ git checkout <branch>

# 合并分支
## --no-ff:fast-forward合并也可以建立合并提交。
$ git merge <branch>

标签操作

1
2
3
4
5
6
7
8
9
10
11
12
# 查看标签列表
## -n:显示标签的注解
$ git tag

# 建立标签
$ git tag <tagname>

# 建立含批注的标签
$ git tag -a <tagname>

# 删除标签
$ git tag -d <tagname>

提交记录操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 修改最近的提交记录
## --amend:覆盖现在的分支最前面的提交
$ git commit --amend

# 只修改最近的提交记录的注解
$ git commit --amend

# 修改过去的提交记录
$ git rebase -i <commit>
## 如果指定提交之后再次指定提交,就会显示提交清单。请在清单里找出要修改的提交,将该行的 “pick” 改成 “edit”,之后保存并退出。
## 接着,编辑要修改的文件,保存文件之后指定--amend选项,以执行提交。
$ git commit --amend
## 最后,指定--continue选项以执行rebase
$ git rebase --continue

远端操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 复制现有的远程数据库
$ git clone <url>
$ git clone <版本库的网址> <本地目录名>

# 复制现有的远程数据库
$ git remote add <name> <url>

# 显示远程数据库列表
## -v:显示远程数据库的详细情况
$ git remote

# 在远程数据库的分支创建本地数据库的分支
$ git checkout <branch>
## 使用最新版本的Git,用chekout命令参数指定远程数据库的分支,就可以通过远程数据库的分支在本地数据库创建分支。
## 如果因为您的版本太旧而不能创建,请按照下面的方法在branch命令创建分支。
$ git branch <branchname> origin/<branch>

# 在远程数据库创建分支/反映修改内容到分支
## -u:追踪在远程数据库的目标分支。这样,在执行push或fetch/pull命令时即使省略了repository,也可以正确地显示/读取修改内容。
$ git push <repository> <refspec>

# 查看远程数据库分支的修改内容
## 语法:
$ git fetch <远程仓库名> <分支名>
$ git fetch <repository> <refspec>

# 读取远程数据库的分支的修改内容
$ git pull <repository> <refspec>

# 删除远程数据库的分支
$ git push --delete <repository> <branchname>
## 1.7以前的Git版本不能使用--delete选项,所以请做以下指定
$ git push <repository> :<branchname>

# 建立远程数据库的标签
## -tags:把本地数据库里所有的标签添加到远程数据库
$ git push <repository> <tagname>

# 删除远程数据库的标签
$ git push --delete <repository> <tagname>
## 1.7以前的Git版本不能使用--delete选项,所以请做以下指定:
$ git push <repository> :<tagname>

# 修改已注册的远程数据库的电子邮件地址
$ git remote set-url <name> <newurl>

# 修改已注册的远程数据库
$ git remote rename <old> <new>

Git 设定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 设定 用户名/电子邮件地址
## --global:对所有数据库有效
$ git config --global user.name <username>
$ git config --global user.email <mailaddress>

# 输出彩色
$ git config --global color.ui auto

# 设定命令的别名
$ git config --global alias.<aliasname> <commandname>

# 把不需要用的文件归类到非管理对象
$ echo <filename> >> .gitignore
## 记录为.gitignore的文件是Git的非管理对象,但是需要提交.gitignore本身

# 管理空分支
$ cd <dirname>
$ touch .gitkeep
## 在Git, 空分支不是管理对象。因此需要把随意的文件放入分支里,使用任何文件名称都可以。按照惯例,一般使用.gitkeep名称。

# 显示设定清单
$ git config --global --list

# 通过代理主机连接http
## 在.gitconfig文件的http项目添加以下的设定
[http]
proxy = <代理主机的电子邮件地址>:<代理主机的端口号码>
## config命令设定
$ git config --global http.proxy <代理主机的电子邮件地址>:<代理主机的端口号码>

# 通过需要用户认证的代理主机连接http
## 在.gitconfig文件的http项目添加以下的设定
[http]
proxy = http://<用户名>:<密码>@<代理主机的电子邮件地址>:<代理主机的端口号码>
## config命令设定
$ git config --global http.proxy http://<用户名>:<密码>@<代理主机的电子邮件地址>:<代理主机的端口号码>

暂存(Stash)操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 暂时保存现状的操作
$ git stash save
## 可以省略save,也可以指定save之后显示内容的信息。

# 显示暂存列表
$ git stash list

# 恢复暂存的操作
$ git stash pop
## 如果不指定参数,在对比操作中可以复原到最新的操作。指定类似stash@{1}的参数,可以复原特定的操作。

# 删除暂存的操作
$ git stash drop
## 如果不指定参数,在对比操作中会删除最新的操作。指定类似stash@{1}的参数,可以删除特定的操作。

# 删除所有暂存的操作
$ git stash clear

Git Flow 操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 在项目中设置 Git Flow
$ git flow init -d

# 开始新功能
$ git flow feature start feature_branch

# 完成 feature 开发,并提交到 feature 分支
$ git add .
$ git commit -m "feature"
$ git push --set-upstream origin feature/feature_branch

# 完成一个功能(会把我们的工作整合到主 develop 分支中)
$ git flow feature finish feature_branch

# 创建 release
## 当你认为现在在 “develop” 分支的代码已经是一个成熟的 release 版本时,这意味着:
## 第一,它包括所有新的功能和必要的修复;
## 第二,它已经被彻底的测试过了。
## 如果上述两点都满足,那就是时候开始生成一个新的 release 了
$ git flow release start 1.1.5

# 完成 release
$ git flow release finish 1.1.5
## 这个命令会完成如下一系列的操作:
## 1. 首先,git-flow 会拉取远程仓库,以确保目前是最新的版本。
## 2. 然后,release 的内容会被合并到 “master” 和 “develop” 两个分支中去,这样不仅产品代码为最新的版本,而且新的功能分支也将基于最新代码。
## 3. 为便于识别和做历史参考,release 提交会被标记上这个 release 的名字(在我们的例子里是 “1.1.5”)。
## 4. 清理操作,版本分支会被删除,并且回到 “develop”。

# 创建 hotfix
## 很多时候,仅仅在几个小时或几天之后,当对 release 版本作做全面测试时,可能就会发现一些小错误。
## 在这种情况下,git-flow 提供一个特定的 “hotfix” 工作流程
##(因为在这里不管使用 “功能” 分支流程,还是 “release” 分支流程都是不恰当的)。
$ git flow hotfix start hotfix_branch
## 这个命令会创建一个名为 “hotfix/missing-link” 的分支。
## 因为这是对产品代码进行修复,所以这个 hotfix 分支是基于 “master” 分支。

## 完成 Hotfixes
$ git flow hotfix finish hotfix_branch

安装 gitflow

Mac

1
2
3
4
5
6
7
8
9
10
11
12
# 使用 brew 安装
$ brew install git-flow

# 使用 wget 安装
$ wget --no-check-certificate -q -O - https://github.com/nvie/gitflow/raw/develop/contrib/gitflow-installer.sh | sudo bash

# 使用 curl 安装
$ curl -L -O https://raw.github.com/nvie/gitflow/develop/contrib/gitflow-installer.sh
sudo bash gitflow-installer.sh

# 确认安装
$ git flow version

常用操作场景

将已有项目添加到github

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建说明文档
$ touch README.md

# 初始化本地仓库
$ git init

# 添加全部已经修改的文件,准备commit 提交
$ git add .
# 该命令效果等同于 git add -A

# 将修改后的文件提交到本地仓库
$ git commit -m ‘提交说明’

# 连接到远程仓库,并将代码同步到远程仓库
$ git remote add origin 远程仓库地址
$ git push -u origin master -f

## 注意事项

- git push -u origin master等同于git push。
- 如果是多人协作开发的话,一定要先 git pull ,将 github 的代码拉取到本地,这样在 merge 解决冲突的时候稍微简便些。
- 如果有多个远程仓库 或者 多个分支, 并且需要将代码推送到指定仓库的指定分支上,那么在 pull 或者 push 的时候,就需要 按照下面的格式书写:

$ git pull 仓库别名 仓库分支名
$ git push 仓库别名 仓库分支名

Git Flow

Git GitFlow
git checkout -b develop git flow init
git checkout develop
git checkout -b feature_branch
git flow feature start feature_branch
git checkout develop
git merge feature_branch
git flow feature finish feature_branch
git checkout develop
git checkout -b release/1.1.5
git flow release start 1.1.5
git checkout master
git merge release/1.1.5
git flow release finish 1.1.5
git checkout master
git checkout -b hotfix_branch
git flow hotfix start hotfix_branch
git checkout master
git merge hotfix_branch
git checkout develop
git merge hotfix_branch
git branch -D hotfix_branch
git flow hotfix finish hotfix_branch

Git同步Github和Coding.net代码

在.git/config里加上:

1
2
3
[remote "all"]
url = https://git.coding.net/iamwlb/kubernetes.git
url = https://github.com/iamwlb/kubernetes.git

1
$ git push all

使用Git LFS

1
2
3
4
5
6
7
8
9
10
# 安装
$ brew install git-lfs

# 使用
$ git lfs install # 只需要设置一次
$ git lfs track "*.rpm"
$ git add .gitattributes
$ git add file.rpm
git commit -m "Add rpm file"
git push origin master

GitHub创建gh-pages分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 在GitHub上手动创建分支
## 【点击】“Branch:master”,在文本框中输入“gh-pages”。

# 初始化
$ git init
$ git remote add origin https://github.com/iamwlb/kubernetes.git

# 迁出分支
$ git fetch
remote: Counting objects: 49, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 49 (delta 5), reused 46 (delta 5), pack-reused 0
Unpacking objects: 100% (49/49), done.
From https://github.com/iamwlb/kubernetes
* [new branch] gh-pages -> origin/gh-pages
* [new branch] master -> origin/master
$ git checkout gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

# 迁入分支
## 在当前目录中复制或创建要提交的文件。
$ git add .
$ git commit -m "update"
$ git push origin gh-pages

Git工作流分类

分类 图示 适用场景 操作步骤/说明
集中式工作流 git-workflow-svn.png - 个人
- 小型团队
- SVN向Git迁移过渡
1. 初始化中央仓库
2. 克隆中央仓库
3. 开发功能
4. pull/push
功能分支工作流 git-workflow-feature_branch.png - 8-12人团队 1. 创建分支
2. 切换分支
3. 推送分支
4. 切换分支
5. 功能开发
6. 提交分支
7. 测试
8. Pull requests
9. Merge pull request
10. 切换到master分支
11. pull
12. 删除本地跟远程分支
GitFlow工作流 git-workflow-release-cycle-4maintenance.png - 大型团队
- 开源项目
版本号命名:v大版本-功能版本-补丁版本。如:
- v1.1.0
- 1.1.1
- 1.2.0。步骤如下:
1. 创建develop分支
2. 切换develop分支
3. 推送
4. 基于develop创建分支(feature功能1)
5. 切换到feature
功能1分支
6. 开发功能
7. 提交
8. Pull reauest到develop
9. Merge pull request
10. 基于develop分支创建release—v1.0.0分支
11. 切换到release-v1.0.0分支
12. pull
13. 测试
14. 推送
15. Pull requests到master
16. Merge pull request
17. 基于master创建标签(1.0.0-release)
18. 推送
19. 基于标签创建新分支(hotfix-问题序号)
20. 修复bug
21. 提交
22. Pull requests
23. Merge pull request
24. 创建分支(release_1.0.1)
25. 推送
26. 删除整个过程中产生的分支
Forking工作流 git-workflow-forking.png 跨国团队 Forking 工作流是分布式工作流,充分利用了 Git 在分支和克隆上的优势。可以安全可靠地管理大团队的开发者(developer),并能接受不信任贡献者(contributor)的提交。
Pull Requests pull-request.png - 功能分支工作流
- GitFlow工作流
- Forking工作流
Pull requests 让开发者更方便地进行协作的功能,提供了友好的 Web 界面可以在提议的修改合并到正式项目之前对修改进行讨论。

常见问题

master -> master (non-fast-forward)错误

问题描述

在git push时,提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
git push -u origin master
To https://github.com/iamwlb/kubernetes.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/iamwlb/kubernetes.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
192:kubernetes iamwlb$ git push -f
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

git push --set-upstream origin master

解决办法

办法1

1
$ git push -u origin master -f

办法2

1
2
$ git pull 
$ git push -u origin master -f

our local changes to the following files would be overwritten by merge

问题描述

1
2
3
4
5
6
7
8
9
10
11
12
13
$ git pull
remote: Enumerating objects: 22, done.
remote: Counting objects: 100% (22/22), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 15 (delta 10), reused 1 (delta 0)
Unpacking objects: 100% (15/15), done.
From https://git.coding.net/iamwlb/blog
d5069b8..a8dff80 master -> origin/master
Updating a7f9911..a8dff80
error: Your local changes to the following files would be overwritten by merge:
db.json
Please, commit your changes or stash them before you can merge.
Aborting

解决办法1

如果希望保留生产服务器上所做的改动,仅仅并入新配置项, 处理方法如下:

1
2
3
4
$ git stash
$ git pull
$ git stash pop
$ git diff -w +文件名 # 确认代码自动合并的情况

解决办法2

如果希望用代码库中的文件完全覆盖本地工作版本,方法如下:

1
2
$ git reset --hard
$ git pull

Authentication failed for又不弹出用户名和密码 解决办法

1
$ git config –-global user.email "xxx@qq.com"

Git-warning: CRLF will be replaced by LF in

问题描述

1
2
$ git add .
warning: CRLF will be replaced by LF in XXX . The file will have its original line endings in your working directory.

问题分析

说明
CRLF windows 环境下的换行符
LF linux 环境下的换行符

这个警告的意思,就是文件中存在两种环境的换行符,git 会自动替换 CRLF 为 LF ,所以提示警告。

解决办法

如果是Mac:

1
2
3
# 将设置中自动转换功能关闭
$ git config core.autocrlf false
$ git config --global core.autocrlf false

git commit 报错

问题描述

1
2
3
4
$ git commit -m "添加CROS、Swagger配置文件"
error: insufficient permission for adding an object to repository database .git/objects
error: insufficient permission for adding an object to repository database .git/objects
error: Error building trees

解决办法

1
2
$ sudo chown -R $USER:$USER "$(git rev-parse --show-toplevel)/.git"
$ sudo chown -R $(id -u):$(id -g) "$(git rev-parse --show-toplevel)/.git"

推荐

参考

坚持原创技术分享,您的支持将鼓励我继续创作!
0%