Git 基操1
Git 基础
工作区、暂存区 和版本库
Git 工作区、暂存区和版本库概念
- 工作区(Working Directory):修改后的文件或新增的文件,未进行 staged 和 commit 操作;Git Fork 中对应 Unstaged 视图里的文件
- 暂存区(stage):英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
- 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
- 图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树。
git 命令在不同区切换
- git add 工作区→暂存区 (就是把文件修改添加到暂存区)
- git commit 暂存区→版本库(就是把暂存区的内容提交到当前分支)
- git diff 区别
- git diff 是工作区 (work dict) 和暂存区 (stage) 的比较
- git diff –cached 是暂存区 (stage) 和分支 (master) 的比较
- git 管理方式
git 管理的是修改而不是文件,如一个文件修改一行,再重命名,提交;git 会识别出修改 + 重命名操作,而不是像 SVN 删文件 + 新文件操作 - 丢弃 git 工作区和暂存区修改
- git checkout .
会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
1
2
3
git checkout .
git checkout -- <file> 命令时
- git checkout HEAD .
会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
1
git checkout HEAD . 或者 git checkout HEAD <file> 命令时
- git reset
丢弃暂存区修改 (丢弃已经 add 的文件,把暂存区修改撤销掉恢复到 unstage 状态,重新放回工作区)
git reset HEAD readme.txt
_git reset_
既可以回退版本,也可以把暂存区的修改回退到工作区
1
2
- 删除文件
- 工作区删除, 然后add到暂存区
- git rm
git rm test.txt
git 中文件的各个状态
- unstaged - git 仓库中没有此文件的相关记录
- modified - git 仓库中有这个文件的记录,并且此文件当前有改动
- staged - 追加,删除或修改的文件被暂时保存,这些追加,删除和修改并没有提交到 git 仓库
- committed - 追加或修改的文件被提交到本地 git 仓库(git 仓库中大部分都是这种文件,所以 git status 不显示这些文件)
git 基本命令
git init 初始化为 git 仓库 (init)
git init
在当前文件夹下生成.git 目录,完成初始化,此时此文件夹下的所有文件处于 unstaged 状态
git clone 克隆仓库 (clone 已经存在的远程仓库)
git clone {要获取库的URL}
获取远程库到当前文件夹
git clone https://github.com/hacket/NetRequest.git
git clone --depth 1
clone 最近一次 commit
git add 将文件添加到暂存区 (add)
- git add,a.text 的文件变为 staged 状态,其他文件还是 unstaged 状态
git add a.text
add 所有git add .
- git rm
git rm --cache a.text
恢复为原先状态(变为 unstaged) - git reset
取消刚才的暂时保存,状态变回 modifiedgit reset test.c
git commit 保存到仓库 (commit)
git commit -m 'a.text'
git log 查看提交记录 (log)
- 每个提交都列出了修改过的文件, 以及其中添加和移除的行数,并在最后列出所有增减行数小计
git log --stat
- 每个提交 放在一行显示 另外还有
short
,full
和fuller
可以用,展示的信息或多或少有些不同
git log --pretty=oneline
- 查看 log 显示较少信息
git log
- 查看 log 显示很多信息
git log --pretty=raw
git remote xxx
Git Remote 是一个指针,它指向通常托管在远程服务器上的存储库的另一个副本
- git remote -v 列出现有的仓库并查看其名称和 URL
❯ git remote -v
origin git@github.com:hacket/king-assist.git (fetch)
origin git@github.com:hacket/king-assist.git (push)
- git remote add {远程库的名字 (一般为 origin)} {远程库的 URL} 为一个仓库添加远程 url
git remote add origin https://github.com/hacket/NetRequest.git
- git remote set-url {远程库的名字 (一般为 origin)} {远程库的 URL}
git remote set-url 命令的实际作用是使用指向远程存储库的新 URL 更新存储库 .git/config文件
1
2
3
4
5
[remote "origin"]
url = git@gitserver.com:user/repo_name.git
fetch = +refs/heads/*:refs/remotes/origin/*
远程 URL 可以以 HTTPS 或 SSH 开头。如果未指定协议,则默认为 SSH。该 URL 可以在 Git 托管服务的存储库页面上找到。
常用 git config
- 设置 git status 颜色
git config --global color.status auto
- 设置全局 username 和 email
git config --global user.name "hacket"
git config --global user.email "zeng_fansheng@sina.com"
git status 查看状态
git status
git push、pull、fetch
git push 推送至远程仓库
git push {远程库的名字} {要推送的分支}
git push origin master
默认 Git 有条主分支 master
,也就是我们 hello
文件 commit
所在分支.
git pull fetch 远端更新并 merge
git pull {远程库的名字} {要推送的分支}
1
git pull origin master
git reset (git 版本回退)
HEAD
概念
在 Git 中,在 Git 中,用HEAD
表示当前版本;上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上 100 个版本写 100 个^
比较容易数不过来,所以写成HEAD~100
。- 回退到上一个版本
回退到上一个版本,就可以使用git reset
命令:
git reset --hard HEAD^
–hard 参数?
此时 readme.txt 内容已经变化,git log
也已经看不到之前的提交了,只能看到上一个版本的提交 log。
- 回退到未来版本
如果我还想回到最开始提交,只要命令行没有关闭,找到提交的commit id
,就可以回到未来指定的某个版本:
git reset --hard 5484
- 为什么 git 回退速度这么快?
因为 Git 在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,Git 仅仅是把 HEAD 从指向要回退的版本append GPL
:
改为指向add distributed
:
然后顺便把工作区的文件更新了。所以你让HEAD
指向哪个版本号,你就把当前版本定位在哪。 - 找不到之前
commit id
,用git reflog
用来记录你的每一次命令操作:
git reset --hard d769c1c
git 远程仓库操作
- 简单查看 - 所有仓库,只能查看远程仓库的名字
git remote
- 查看更多内容 - 所有仓库,远程仓库的名字及 git 地址
git remote -v
- 查看单个仓库的信息
git remote show [remote-name]
- 新建远程仓库
git remote add [shortname] [url]
- 修改远程仓库
git remote rename [oldnanme] [newname]
- 删除远程仓库
git remote rm [remote-name]
- 获取远程仓库的数据
git fetch [remote-name] (获取仓库的所有更新,但是不自动合并当前分支)
git pull (获取仓库的所有更新, 并且自动合并到当前分支)
- 上传数据到远程仓库
git push [remote-name] [branch-name]
git branch 分支管理
本地分支、远程分支、跟踪分支 (tracking)、HEAD 分支
- 本地分支 (local branch)
我们自己本地 git 仓库所拥有的分支
- 远程分支 (remote branch)
和本地分支一样,只是存在于远程服务器,我们无法移动它,必须要在和服务器交互更新到本地来的代码移动
- 跟踪分支 (tracking branch)
它是一个本地分支,只是它对应了一个远程分支,叫做 跟踪分支;或者从远程分支 checkout 出来的本地分支,叫做 跟踪分支。跟踪分支是一种和远程分支有直接联系的本地分支。在 clone
仓库时,git 通常会自动创建一个名为 master
的分支来跟踪 origin/master
。
HEAD
git 中的分支,其实本质上仅仅是个指向 commit 对象的可变指针。git 是如何知道你当前在哪个分支上工作的呢?
它保存着一个名为 HEAD
的特别指针。在 git 中,它是一个指向你正在工作中的本地分支的指针,可以将 HEAD 想象为当前分支的别名。
git reset HEAD <file>
指的是恢复到当前分支中文件的状态git log
日志展示中HEAD -> master
指的是:当前分支指向的是 master 分支。
The HEAD: Pointer to last commit snapshot, next parent
The HEAD in Git is the pointer to the current branch reference, which is in turn a pointer to the last commit you made or the last commit that was checked out into your working directory. That also means it will be the parent of the next commit you do. It’s generally simplest to think of it as HEAD is the snapshot of your last commit.
查看 HEAD:
cat .git/HEAD
Ref: refs/heads/master
本地分支
1、创建分支并切换
创建一个叫做 “feature_hacket”
的分支,并切换过去,此时 git commit 就提交到该 branch
git checkout -b feature_hacket
git checkout
命令加上 -b
参数表示创建并切换,相当于两条命令:
git branch feature_hacket
git checkout feature_hacket
注意: 在哪个分支拉取新的分支,那么就从这个分支的拉取,新拉取分支的 HEAD 和所在分支的节点信息一致。
使用 git init 初始化,然后立即 git branch,不会出现任何分支包括 master,因为 git 的分支必须指向一个 commit,没有任何 commit 就没有任何分支,提交第一个 commit 后 git 自动创建 master 分支
2、查看分支状态
git status
- 查看当前所在分支
git checkout
3、切换分支
- 切换回主分支
git checkout master
未 commit 的工作区文件和 stage 文件是可以灵活地在且仅在任一 branch 分支的,切换到新的分支也可以看到这些文件,commit 后的就看不到了
4、更新和合并
- 新你的本地仓库至最新改动,获取(fetch) 并 合并(merge) 远端的改动
git pull
- 合并其他分支到你的当前分支(例如 master),记得 push
git merge <branch>
git pull
和 git merge
两种情况下,git 都会尝试去自动合并改动。不幸的是,自动合并并非次次都能成功,并可能导致 冲突(conflicts)。 这时候就需要你修改这些文件来人肉合并这些 冲突(conflicts) 了。
- 在合并改动之前,也可以使用如下命令查看
git diff <source_branch> <target_branch>
git rebase
替代git merge
将分支 dev2222 合并到 mastersetUs
git rebase dev2222
5、删除分支
删除分支,需要当前不在这个分支才能删除
把新建的分支 feature_hacket
删掉,如果没有 merge 到 master,会报错
git branch -d feature_hacket
强制删除可以使用git branch -D feature_hacket
除非你将分支推送到远端仓库,不然该分支就是 不为他人所见的:git push origin <branch>
6、rest 丢弃 commit 的内容
丢弃你所有的本地改动与提交,可以到服务器上获取最新的版本并将你指定的主分支指向到它
git fetch origin
git reset --hard origin/feature_hacket
7、stash 暂存
git stash 这个命令可以将当前的工作状态保存到 git 栈,在需要的时候再恢复。
- 默认
1
2
git stash
# 保存当前的工作区与暂存区的状态,把当前的修改的保存到git 栈,等以后需要的时候再恢复,git stash 这个命令可以多次使用,每次使用都会新加一个`stash@{num}`,num是编号
- 带消息的 Git stash
1
2
3
git stash save "Your stash message"
# 或者
git stash push -m "Your stash message"
- 列举所有 stash
1
2
git stash list
# 查看当前stash的所有内容
- 恢复 stash,但不删除 stash
1
2
3
4
git stash apply
git stash apply stash@{0}
# git stash apply [–index] [stash_id] 除了不删除恢复的进度之外,其余和`git stash pop` 命令一样。
# 将堆栈中的内容恢复到当前分支下。这个命令不同于 git stash pop。该命令不会将内容从对堆栈中删除,也就是该命令能够将堆栈的内容多次运用到工作目录,适合用与多个分支的场景
- 恢复最新的 stash,并删除该 stash
1
2
3
4
5
6
7
# git stash pop [–index] [stash_id]
git stash pop # 恢复最新的进度到工作区。git默认会把工作区和暂存区的改动都恢复到工作区。
git stash pop --index #恢复最新的进度到工作区和暂存区。(尝试将原来暂存区的改动还恢复到暂存区)
git stash pop stash@{1} #恢复指定的进度到工作区。stash_id是通过git stash list命令得到的
# 默认恢复git栈中最新的一个`stash@{num}`,建议在git栈中只有一条的时候使用,以免混乱
# 注:该命令将堆栈中最新保存的内容删除
- 从堆栈中移除指定的 stash
1
2
3
4
5
git stash drop
git stash drop stash@{$num}
# git stash drop [stash_id]
# 删除一个存储的进度。如果不指定stash_id,则默认删除最新的存储进度。
- 移除全部 stash
1
git stash clear
- 查看差异
1
2
git stash show
# 查看堆栈中最新保存的stash和当前⽬录的差异,显⽰做了哪些改动,默认show第一个存储
8、查看分支
基本语法是:git branch 参数
1
2
3
4
5
6
git branch 列出本地已经存在的分支,并且当前分支会用*标记
git branch -r 查看远程版本库的分支列表
git branch -a 查看所有分支列表(包括本地和远程,remotes/开头的表示远程分支)
git branch -v 查看一个分支的最后一次提交
git branch --merged 查看哪些分支已经合并到当前分支
git branch --no-merged 查看所有未合并工作的分支
不加参数
或-l
查看本地所有分支,当前分支前面会标一个*
号
1
2
3
4
5
6
7
8
> git branch
#或
> git branch -l
9.2.0/user
9.2.0/user-wkg
9.2.0/user_lizhipei
* master # 当前所在分支
-r
查看远程分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> git branch -r
origin/6.0.0
origin/6.2.4
origin/6.2.8
origin/6.5.2
origin/6.5.6
origin/6.6.0
origin/6.6.2
origin/6.6.4
origin/6.6.6
origin/6.6.8
origin/6.7.2
origin/6.7.3
origin/6.7.4
origin/6.7.6
# 分支太多,按enter继续,按q退出
-a
查看所有本地和远程分支 (远程分支会用红色表示出来)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
> git branch -r
9.2.0/user
9.2.0/user-wkg
9.2.0/user_lizhipei
* master
remotes/origin/6.0.0
remotes/origin/6.2.4
remotes/origin/6.2.8
remotes/origin/6.5.2
remotes/origin/6.5.6
remotes/origin/6.6.0
remotes/origin/6.6.2
remotes/origin/6.6.4
remotes/origin/6.6.6
-vv
或-vva
参数,查看本地/远程分支更详细信息(如正在使用的本地或远程分支、提交 ID 和提交信息等)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看本地分支的详细信息
git branch -vv
9.2.0/user 432193e7e4 [origin/9.2.0/user] Merge branch '9.2.0/ft-login-refactor-conflict' into '9.2.0/user'
9.2.0/user-wkg e139b9583f [origin/9.2.0/user-wkg] fix(WEB-7760):付费会员-"buy_when": null, "trial_status": 0,的情况下,返回了产品
包价值引导 终端没展示
9.2.0/user_lizhipei 34d2ed07a7 [origin/9.2.0/user_lizhipei] feat(SAB-51566):vn、tw、uk、mx、se域名支持onelink
* master 630a51be2b [origin/master] Merge branch '9.2.0/release' into 'master'
# 查看本地和远程分支的详细信息
> git branch -vva
9.2.0/user 432193e7e4 [origin/9.2.0/user] Merge branch '9.2.0/ft-login-refactor-conflict' into '9.2.0/user'
9.2.0/user-wkg e139b9583f [origin/9.2.0/user-wkg] fix(WEB-7760):付费会员-"buy_when": null, "trial_status": 0,的情况下,返回了产品包价值引导 终端没展示
9.2.0/user_lizhipei 34d2ed07a7 [origin/9.2.0/user_lizhipei] feat(SAB-51566):vn、tw、uk、mx、se域名支持onelink
* master 630a51be2b [origin/master] Merge branch '9.2.0/release' into 'master'
remotes/origin/6.0.0 b6f1a5d101 fix:fresco gif
remotes/origin/6.2.4 11c169e413 6.2.4 build
remotes/origin/6.2.8 fe4147c925 6.2.8修复
remotes/origin/6.5.2 2e6f1929ae URL modify
- 打印当前本地分支名
1
2
3
4
5
6
7
8
9
10
11
# git symbolic-ref --short HEAD
❯ git symbolic-ref --short HEAD
test_git_hooks
# git rev-parse --abbrev-ref HEAD
❯ git rev-parse --abbrev-ref HEAD
test_git_hooks
## --abbrev-ref 表示输出所给对象不会混淆的短名,不加 --abbrev-ref 时,会打印出HEAD对应的hash值:
❯ git rev-parse HEAD
0f5311feaa12335e316e5bd550b8128bd430b447
9、合并分支
1、fast-forward 合并
git merge
用于合并指定分支到当前分支。
1
git merge dev
注意到上面的
Fast-forward
信息,Git 告诉我们,这次合并是 “ 快进模式 “,也就是直接把master
指向dev
的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward
。
2、有冲突的 merge,当 Git 无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成
用带参数的 git log
也可以看到分支的合并情况
1
git log --graph --pretty=oneline --abbrev-commit
10、删除分支
1
git branch -d dev
因为创建、合并和删除分支非常快,所以 git 鼓励你使用分支完成某个任务,合并后再删除掉分支,这和直接在 master
分支上工作效果是一样的,但过程更安全。
远程分支
更新远程代码到本地有两个命令,fetch 和 pull。
- fetch : 是将远程代码更新到本地,但不会执行合并操作,需要自己查看,解决冲突,然后 merge 新来的代码合并到我们自己的分支
git fetch 远程仓库 [本地分支]:[远程分支]
1
git fetch origin dev_2:master
- pull : 将这两个操作合成了一步,直接更新服务器代码更新并合并到到本地指定分支,当然遇到冲突也必须要自己解决
- push
git push 远程仓库 [远程分支]:[本地分支]
1
git push origin master:dev_2
- 推送本地分支到远程仓库
1
git push origin dev_22
- 删除远程分支
git push 远程仓库 :远程分支
1
git push origin :dev_2
1
git push --delete origin dev_22
远程分支的 stale 状态
git remote show origin
原因: 其他人删除了远程仓库,我 fetch 和 pull 这些远程仓库还在,使用 git branch -a
在还在,都是 stale 状态。
解决: 使用 prune
1
git remote prune origin
更简单的方法是使用这个命令,它在 fetch 之后删除掉没有与远程分支对应的本地分支:
1
git fetch -p
跟踪分支 (tracking branch)
1、创建跟踪分支和远程分支名一样
1
git checkout --track origin/dev_2
2、创建一个跟踪分支并切换到该分支,并指定本地分支名字git checkout -b [本地分支名] [远程名]/[分支名]
如创建 dev_4 本地分支并 track 远程 master 分支
1
git checkout -b dev_4 origin/master
1
git branch -f --track dev_3 origin/master
git tag 标签
每发布一个版本,通常会在版本库中打一个 tag。将来可以将这个 tag 版本取出来。tag 和 branch 类似,只是 branch 可以移动,而 tag 不能移动。
1、查看 tag
- 查看所有 tag
git tag
- 查看某个 tag
git show [tag-name]
2、新建 tag
- 轻量级 tag,默认 tag 是打在最新提交的 commit 上
git tag [tag-name]
- 带标注的 tag
git tag -a [tag-name] -m "tag message"
- 后期追加 tag,创建一个叫做 v1.0.0 的 tag
git tag v1.0.0 1b2e1d63ff
1b2e1d63ff
是你想要标记的提交 ID 的前 10 位字符,通过 git log 获取提交 ID。你也可以用该提交 ID 的少一些的前几位,只要它是唯一的。
- 删除 tag
git tag -d [tag-name]
3、push 到远端
- push 一个 tag
1
git push origin <tagname>
- 一次性推送全部尚未推送到远程的本地 tag
1
git push origin --tags
- 删除远程 tag,先删除本地,再 push
1
2
git tag -d v1.1
git push origin :refs/tags/v1.1
git tag –contain
1
2
-contains <commit> print only tags that contain the commit // 打印包含该commit的tags
--no-contains <commit> print only tags that don't contain the commit // 打印不包含该commit的tags
Git config 配置
修改的都是用户目录下的 .gitconfig
文件,这个文件是全局配置
git config 介绍
Git 有一个工具被称为 git config,它允许你获得和设置配置变量;这些变量可以控制 Git 的外观和操作的各个方面。这些变量可以被存储在三个不同的位置:
/etc/gitconfig
文件:针对整个系统。包含了适用于系统所有用户和所有库的值。如果你传递参数选项--system
给 git config,它将明确的读和写这个文件。~/.gitconfig
文件 :针对单个用户。在用户的主目录。你可以通过传递--global
选项使 Git 读或写这个特定的文件。.git/config
:针对单个仓库。位于 git 目录的 config 文件 (也就是 .git/config) :无论你当前在用的库是什么,特定指向该单一的库。每个级别重写前一个级别的值。因此,在.git/config 中的值覆盖了在/etc/gitconfig 中的同一个值。
color.status 设置 git status 颜色
1
git config --global color.status auto
mergetool.keepBackup git mergetool 不再生成烦人的备份文件(*.orig
)
1
git config --global mergetool.keepBackup false
你的标识 (Your Identity) :user.name 和 user.email 配置全局用户和邮箱
每次提交时都会使用到这 2 个信息。
git config --global user.name "hacket"
git config --global user.email "zeng_fansheng@sina.com"
core.protectNTFS
忽略路径中的转义字符,否则在 mac 和 windows 混合路径可能会报错
1
git config --global core.protectNTFS false
git error:invalid path 问题解决(Windows 下)
具体问题:
1
2
3
4
在git clone到本地时遇到报错:
error: invalid path 'src/main/java/com/sankuai/meituan/hive/udf/Aux.java'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
分析: core.protectNTFS
默认为 true。官方解释:If set to true, do not allow checkout of paths that would cause problems with the NTFS filesystem
NTFS 有个路径保护机制,防止文件系统出错
core.autocrlf 禁用换行符转换
1
git config --global core.autocrlf false
你的比较工具 (Your Diff Tool)
1
git config --global merge.tool vimdiff
查看 git config
查看所有
1
git config --list
查看某一个
1
git config user.name
Git 冲突
手动解决冲突
查看冲突
1
git diff
分析
<<<<<<<
标记冲突开始,后面跟的是当前分支中的内容,HEAD 指向当前分支末梢的提交=======
之后,>>>>>>>
之前是要 merge 过来的另一条分支上的代码。 »»»>之后是另外一个 commit 的 id。- 对于简单的合并,手工编辑,然后去掉这些标记,最后像往常的提交一样先 add 再 commit 即可。
解决后再次添加 add:git add .
再 commit:git commit -m 'xxx'
最后 push:git push origin master
merge 工具解决
git mergetool
执行这句就会生成几个文件
上面是 "LOCAL"
、"BASE"
、"REMOTE"
,它们只是提供解决冲突需要的信息,是无法编辑的。
下面一个窗口是合并后的结果,可以手动修改,也可以点击相应颜色的箭头选择 “LOCAL” 或者 “REMOTE”。
readme_BACKUP_8264.txt 冲突文件的备份
readme_BASE_8264.txt 冲突前修改的
readme_LOCAL_8264.txt 本地修改的
readme_REMOTE_8264.txt 远程库的
Beyond Compare
具体见 [[Beyond Compare4]]
TortoiseGit→Edit conflicts
Android Studio Merge Tool
Vscode
见 [[Git GUI工具#VS Code 解决 Git 冲突]]
Git Fork 自带
见 [[Git GUI工具#Git fork解决冲突]]
Merge Request 冲突
前提,你在个人开发分支 dev 开发功能,开发完后要提交到 master 分支,master 分支是 protected 的,你开发完毕后,发一个 dev 到 master 的 MR,这时出现了冲突
解决 1:网站上 resolved 按钮(master 要有权限)
在网站上解决冲突,然后提交,这种要求有 master 的权限,但我们一般是没有 master 权限,这种方式不行
解决 2:本地 dev 合并到本地 master(master 要有权限)
本地 master 拉取最新代码,然后将本地 dev 合并到本地 master,处理冲突后推送到远程的 master,GitLab 中的 Merge Request 自动完成合并
如果 master 分支是受保护的分支,并且开发人员的账号没有 merge 的权限,就只能用下面的方案了
解决 3:本地 master 合并到本地 dev 远端 master 会污染 dev 分支
master 拉取远端最新代码,将本地 master 合并到本地 dev,处理冲突后推送到远程的 dev,在 GitLab 中手动点击 Merge(不推荐,会污染分支代码)
这种方式的话, 如果远端是新的代码,合并到 dev 的话,会把 dev 的分支代码给污染了
如果不是 master,而是 release 分支(release 分支包括了所有业务的最新代码),如果将 release 分支的代码 merge 到你的 dev 分支,你的 dev 分支就被污染了
解决 4:临时分支
个人分支→master(master 一般保护,不让推送)
- 本地 master 分支拉取最新的远端 master 分支的代码
- 基于本地 master 拉取一个 dev_temp 分支(此时 dev_temp 拥有最新代码)
- 将 dev 分支合并到 dev_temp 分支,解决好冲突
- 发 dev_temp 到 master 的 MR,此时就没有冲突了
业务分支→release (保护)
一种情况:业务分支 ft-cart-share
合并到 release 冲突 (release 为保护分支,无权限)
- 基于 release 拉临时分支 cart-share-tmp2,将 ft-cart-share 分支合并到 cart-share-tmp2,解决好冲突,发送 MR 合并 cart-share-tmp2 到 release
- 基于 ft-cart-share 分支拉临时分支 cart-share-tmp,将 release 分支合并到 cart-share-tmp,解决好冲突,发送 MR 合并 cart-share-tmp 到 release
这 2 种分支解决冲突没什么区别,都可以,推荐基于 release 拉临时分支
Master→业务分支(都是保护分支)
问题:master
合并到业务分支 user
冲突 (master
为保护分支,user
也是保护分支,无权限)
解决 1:基于 user
拉临时分支 tmp
,将 master
合并到 tmp
分支,解决好冲突,然后将 tmp
发送 MR 合并到 user
解决 2:基于 master
拉临时分支 master-xxx
,将业务分支 user
合并到 master-xxx
,解决好冲突,将 master-xxx
合并到 user
现在 master 合并到业务分支,会有临时分支 master-xxx,如果有冲突,只需要将业务分支合并到临时分支 master-xxx 提交即可;如果还出现编译失败,大概率是业务分支 user 用了旧 master 的 API,但新的 master 将该 API 修改了或删除了,导致编译不过,这种就需要在业务分支改成用 master 最新的 api
其他
.gitattributes
文件
.gitattributes 是一个文本文件,文件中的一行定义一个路径的若干个属性,主要用于定义每种文件的属性,以方便 git 帮我们统一管理。
. gitattributes 文件格式如下:
要匹配的文件模式属性 1 属性 2 …
在. gitattributes 文件的一行中,一个属性(以 text 属性为例)可能有 4 种状态:
- 设置 text
- 不设置 -text
- 设置值 text=string
- 未声明,通常不出现该属性即可;但是为了覆盖其他文件中的声明,也可以! text
.gitattributes 文件中可以定义的属性
.gitattributes 作用详细讲解(git大佬必会技能)
git 修改历史提交信息和提交时间
下载 git-redate
https://github.com/PotatoLabs/git-redate
点我下载git-redate
git 修改提交时间步骤
- 步骤 1:选择要修改时间的 revision
1
2
3
4
5
// 修改前2个
git redate -c 2
// 修改所有
git redate --all
- 步骤 2:选择 1,用 vi 编辑时间
- 步骤 3:强推
git push -f
Ref
.gitignore 模板
各种 gitignore
https://github.com/github/gitignore
在线生成 gitignore
简单的 Android.gitignore 模板
https://github.com/github/gitignore/blob/master/Android.gitignore
https://github.com/lzyzsd/JsBridge/blob/master/.gitignore
gitignore 模板
Android Studio 中 .gitignore 的编写
简单的.gitignore 模板
#built application files
*.apk
*.ap_# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
out/
build/
# Local configuration file (sdk path, etc)
/local.properties
# Windows thumbnail db
Thumbs.db
# OSX files
.DS_Store
# Eclipse project files
.classpath
.project
.settings
# Android Studio
*.iml
.idea
# Local IDEA workspace
.idea/workspace.xml
# Gradle cache
.gradle
#NDK
obj/
# git mergetool backup
*.orig
gitignore.io在线生成模板:android/java/eclipse/idea/linux
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Created by https://www.gitignore.io/api/ndroid,java,eclipse,intellij,linux
# !! ERROR: ndroid is undefined. Use list command to see defined gitignore types !!#
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml
# Sensitive or high-churn files:
.idea/dataSources.ids
.idea/dataSources.xml
.idea/dataSources.local.xml
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
# Gradle:
.idea/gradle.xml
.idea/libraries
# Mongo Explorer plugin:
.idea/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Intellij Patch ###
*.iml
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
### Java ###
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
Git 指令图
Git 指令速查表图
版本控制最佳实践图
Ref
- GitHub 极速入门 - 程序员必备技能
http://www.jianshu.com/p/da9bc509b1d2