git是一个分布式版本控制系统 存在于客户端
github是一个用git做版本控制的项目托管平台。服务器
角色:
Owner Git 系统管理员
Master Git 项目管理员
Developer Git 项目开发人员
Reporter Git 项目测试人员
Guest 访客
Developer是不能向master 和 release-*推送的
Reporter 不能创建合并请求和创建分支 只有项目的读权限,可以创建代码片断
项目管理的分支策略:
一个主干(master):这个主干可以说是最稳定的分支 代码必须cr mr过后才能合入主干 并且会有合入验证
开发分支(feature/dev分支): 这个分支是基于主干拉取的,主要用来进行迭代的开发,定期自动rebase主干,也可以在feature/dev分支基础上拉出个人分支或者其他feature分支
发布分支(release分支):这个分支是当某个迭代做完了,将开发分支的内容测试过了,合入主干后,再基于主干拉出来的发布分支。该分支也是很稳定的,bug最少的
而若是在master分支或者release分支有一些bug需要更改,则 可以基于主干拉取:
bugfix_xx_xx分支:用来对master分支的bugfix操作 并且一定要走MR 命名为 bugfix_来自的分支名_修复的问题
hotfix_xx_xx分支:用来对release分支进行bugfix操作(先合入主干,然后cherrypick合入到release分支) 命名为 hotfix_来自的分支名_修复的问题
注意:
1 若是插入了需求,哪怕是小需求,也尽量别在dev或者feature分支改,还是拉出一个新分支,一个是为了防止忘记在哪里更改,最主要的是防止冲突
2 若是feature分支测出的一些非该feature分支引入的bug,而是master里面的,也是建议基于主干拉取:
bugfix_xx_xx分支:用来对master分支的bugfix操作
3 当pull的时候,应该以rebase的方式进行合并而不是merge的方式,这样git树会比较直,比较清晰
4 MR(merge request)注意:rebase/merge 要自己的分支编译过了才能合入父分支 (最好有相关的mr工具 能要别人CR(code Review)&&构建通过才能合入 特别是跨平台开发 得四个端都得编译过
一、Github注册账户以及创建仓库
不详细讲解
二、安装git客户端
windows:http://msysgit.github.com/
安装过程可以参考:http://blog.csdn.net/renfufei/article/details/41647875/
安装完成后,在文件夹中点鼠标右键会多出一些菜单
如 Git Bash、Git Gui , 说明安装成功
git可以配置访问某个ip的代理
1 open ~/.gitconfig
2 增加
[http "https://skia.googlesource.com"]
proxy = http://127.0.0.1:12639
3 保存文本即可
三、配置Git
1 第一次在本地仓库操作需要先执行git init命令
若无后缀为.git的目录 则要:
git init
你要同步的仓库处用Git Bash Here 打开命令行,输入:Git init
再点击文件夹显示隐藏文件 就可以看到.git后缀的文件夹了
2 为了把本地的仓库传到github,还需要配置SSHKey
这个SSHKey是本地的仓库的密钥 用于和远程仓库连接
配置好了下次导其他项目就可以用这个密钥使用了
2.1在本地创建ssh key
ssh-keygen -t rsa -C "[email protected]"
输入你的邮箱
然后说明会在默认文件id_rsa上生成ssh key,直接点回车就是在默认位置 一般在C盘用户的.ssh文件夹中,也可以在后面加上绝对路径
然后系统要求输入密码,输入密码时不会显示密码
然后重复输入密码,也是不会显示密码
之后创建成功,会提示:
The key's randomart image is:
在存放key 的文件夹下,会有id_rsa.pub和id_rsa的文件
id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥
2.2
打开id_rsa.pub,复制,进入到github官网, 点击Settings,左边选择Deploy Keys,add key
tietle填sshkey1
key填你复制的内容
2.3 验证是否成功,在git bash下输入
ssh -T [email protected]
可能会出现:
The authenticity of host ‘github.com (192.30.255.112)’ can’t be established.
RSA key fingerprint is
原因是: 在存放key的文件夹下,缺失known_hosts文件,直接输入yes,然后输入你的密码即可
若你的key名称不是默认的名称,会出现:
[email protected] Permission denied (publickey)
1 把文件名设置为默认的id_rsa
2
ssh-add ~/.ssh/你的名字
将自己起的名字加入到ssh中
再使用 ssh -T [email protected] 即可
出现:
Hi 5ingwings! You've successfully authenticated, but GitHub does not provide shell access.
就成功了
3 接下来我们要做的就是把本地仓库传到github上去,在此之前还需要设置username和email,因为github每次commit都会记录他们
这是global参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱
name可以为github上的名 只要有标识性即可
git config --global user.name "your name"
git config --global user.email "[email protected]"
成功会显示
SiHao@SiHao-PC MINGW64 /g/Git/MyRepository (master)
要修改直接再重写执行一遍上面的代码即可(至少我的是这样,如果有的人改不了,可以参考:http://blog.csdn.net/sky_miange/article/details/60881282)
4 进入本地仓库(创建了.git文件的目录),右键git bash,添加远程地址
$ git remote add origin [email protected]:yourName/yourRepo.git
后面的yourName和yourRepo表示你在github的用户名和步骤一新建的仓库,加完之后进入.git,打开config,这里会多出一个remote “origin”内容,这就是刚才添加的远程地址,也可以直接修改config来配置远程地址
成功后没有提示
不能同时连接多个远程仓库,要改则
git remote rm origin
再 git remote add
5 提交上传
5.1 先要添加到暂存区(state/index)里面去
git add 要添加的文件名
没有任何提示,说明已经添加成功了
想添加该文件夹下所有文件
git add .
而如果是使用sourcetree等git管理系统,则会有Staged files区,将文件添加入这里,就直接会执行git add命令
5.2 将文件从暂存区提交到本地仓库(repositories)
git commit -m "first commit"
first commit 为提交的注释
成功会
XX files changed
createXXX
createXXX
5.3 我们可以通过
git status
查看是否还有文件未提交或者更新了未被提交
5.4 上传到github(远端)
git push -u origin master
git push命令会将本地仓库推送到远程服务器。实际上是把当前分支master推送到远程
由于远程库是空的,我们第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令
git pull命令则相反。
注意:若你在创建github仓库时,勾选了创建README文件,则需要先把文件同步到本地,再上传提交
error: failed to push some refs to '[email protected]:android-app-development-course/Orienteering.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
通过:
git pull --rebase origin/master
这时,你的本地就会有README文件
再去用git push -u origin master上传
5.4 从现在起,只要本地作了提交,就可以通过如下命令:
git push origin master
把本地master分支的最新修改推送到github上了
6 新建文件
若新建了文件
使用git status
会出现:
$ git status
On branch master
Untracked files:
(use "git add ..." to include in what will be committed)
test.txt
用
git add test.txt
去加入文件到暂存区
再用命令 git commit告诉Git,把文件提交到仓库
git commit -m "test commit"
最后上传到github上
7 内容修改上传
7.1通过git status 查看是否有修改了未上传的
若出现
On branch master
Changes not staged for commit:
(use "git add ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
则说明有文件修改了但是没有上传到暂存区
7.2 查看修改了但没有上传到暂存区的文件
git diff test.txt
7.3 将文件添加到暂存区
git add test.txt
7.4 commit上传到仓库
git commit -m "test commit2"
7.5 添加到远程仓库
git push origin master
git clone 远程仓库地址
带账号密码认证的:
git clone http://userName:password@链接
若账号密码没错,但是还是提示Authentication failed,则去凭证管理中修改一下账号和密码
拉取,但是不merge到workSpace 而是到local repositories
git fetch
拉取,并且会merge到workSpace
git pull
要对文件夹右键,而不是空白处右键
1 查看本地分支
git branch
2 查看远程分支
git branch -r
3 分支切换
git checkout master
git checkout feature-1
4 分支创建
git branch feature-3
创建分支后切换到新分支
git checkout -b feature-3
5 删除分支
git branch -d feature-3
6 本地分支上传到远程
git push origin 本地分支名:远程分支名
7 删除远程分支
git push origin 【这里为空即可】:远程分支名
8 分支合并到主干
git checkout master
git merge 分支名
或者工具 merge master into 分支
9 rebase 变基
含义:我,子分支,現在要重新定义我的参考基准,并且将使用 父分支 当做我的新参考标准
git checkout 要rebase的分支名
git rebase 主干或者其他分支
注意 rebase 要rebase它的父分支
要先commit再rebase 然后再push
如果存在冲突,在文件中可以看到
>>>>>>Head
要rebase的分支的代码
======
现在的分支代码
<<<<<< xxdescription
进行相应的删除或保留
sourcetree中 带感叹号的就是有冲突的 去文件状态中可以看到
merge和rebase的差异
merge是将父分支的内容直接合入到子分支之上,作为一个新的commit,若有冲突,只是与子分支上最近的一个commit作比较和冲突解决
而rebase相当于将子分支嫁接到父分支的最新的commit之上,若有冲突,则是与嫁接过来的子分支上所有commit都比较和冲突解决一次
通过merge的方式会有一个树分叉过去 比较难看
通过rebase的方式不仅不会有一个树分叉过去 而且会把之前从父分支拉出来的树枝,给去掉,相当于直接嫁接到父分支上 形成了一条直线
执行的若是rebase B onto A 相当于把B融入A的分支的上边,则incomming为B分支
若执行的是merge A into B 则相当于把A合入B分支,对改动点生成一个新的提交,则A为incomming
克隆分支
1 可以直接克隆主干,然后去切换分支,但是建议一个文件夹一个分支 不要一个文件夹的分支切来切去,避免混乱
2 克隆分支,用命令:
git clone -b 分支名 http://xxx.xxx.xx.git
//(主干的网址)
查看来源与commit记录
git reflog
查看本地仓库从创建到最新,本地所进行的与项目更改有关的操作 包括已删除的操作
如 可以看到从哪个分支拉出来的以及commit记录和commit记录的编号
git reflog show xxBranchName
查看本地某个分支的与项目更改有关的操作 包括已删除的操作
查看分支从哪个分支拉出来的(只能查看从本地创建的分支)
git reflog --date=local | grep
版本回退
回退的这个commit的记录会被删去
git reset --hard 上面获取的编号(某个commit的SHA1值) 该方式回退不会保存相关内容的变更
git reset --soft 上面获取的编号(某个commit的SHA1值) 该方式回退是会保存要提交的相关内容的变更
若要回退远程库,则执行完这个命令后 然后强制推送到远端
git push -f
只合并某个提交
如某分支dev只想要feature分支的某个提交
则只需找到这个提交的 hash值
git checkout dev
git cherry-pick
当执行完 cherry-pick
以后,将会生成一个新的提交 这个新的提交的哈希值和原来的不同,但标识名一样
若有冲突 和正常的冲突解决方式一样
只获取某个提交 但是不想要这个提交的文案
可以先按上面的 cherry-pick
之后,reset一下,这样相关修改就在本地了 而不会有这条提交记录
# 删除 untracked files
git clean -f
# 连 untracked 的目录也一起删掉
git clean -fd
# 连 gitignore 的untrack 文件/目录也一起删掉 (慎用,一般这个是用来删掉编译出来的 .o之类的文件用的)
git clean -xfd
# 在用上述 git clean 前,墙裂建议加上 -n 参数来先看看会删掉哪些文件,防止重要文件被误删
git clean -nxfd
git clean -nf
git clean -nfd
1 存储当前的变更,并会还原工作区
git stash
2 查看所有贮藏
git stash list
3 使用贮藏
// 使用最近的贮藏
git stash apply
or
git stash apply stash@{0}
//使用第二个贮藏
git stash apply stash@{1}
4 移除贮藏
git stash drop
5 若stash误删除
可以用
git fsck --unreachable // 命令查找所有unreachable记录
git show + // 命令会查找你需要恢复的那一条工作现场 只能查找commit开头的
git stash apply +<你找到的那条记录的key> // 恢复 应用stash
1 显示HEAD提交的SHA1值
git rev-parse HEAD
或者用TortoiseGit 然后右键显示日志 也能在中间部分查看 这个 提交的 SHA1值
常见错误ERROR:
1 git push origin master时,出现
ERROR: Repository not found.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
解决:
1 再三检查用户名或者仓库是否写错
去git remote add origin [email protected]:yourName/repositoryName.git
可以删掉(看上面怎么代码) 再重新输入一次
2 git remote 了 , 却说已经exists了
2.1 可能是你的仓库只有read权限,没有read/write权限 去修改权限
3 可能是你的github的文件没有同步到仓库中,要先pull出来,再push进去
2 fatal: Needed a single revision
invalid upstream 'xx/0.0.3’
解决:分支名写的不正确或不完整 加上 origin/xx/0.0.3
.gitnore文件设置
每个目录都有一个.gitnore的隐藏文件 在这里对该目录下的文件进行gitnore处理
# Built application files
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/dictionaries
.idea/libraries
# Keystore files
# Uncomment the following line if you do not want to check your keystore files in.
#*.jks
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md
#.a .so
#.o
#aar
#BuildConfig
若文件被gitnore了 但是找不到在哪里被gitnore的
可以自己手动 git add -f
文件即可
若文件ignore不了 可以先将远端的文件先push一个remove 然后再加个gitnore
在进行git提交之前,进行预检查
.git/hooks目录下,有以下几个脚本
pre-commit commit之前执行的脚本
prepare-commit-msg commitmsg生成
commit-msg commitmsg生成 常用于进行检测commitmsg的规范
post-commit commit 之后执行的脚本
一、对提交的内容(commitMsg)进行格式检查
<类型> <主题> [解释改动原因] [参考链接、其他资源、关键字]
类型值包含
1.1 设置提交的格式配置:
git config --global commit.template <你的git-commit-template.txt file path>
–global 设置全局的提交模板不仅仅是该Branch
输入git commit 后能将改格式文件打印出来 然后自己可以在上面写内容了(设置好editor)
1.2 进行commitMsg格式检查
通过将自定义的脚本文件 替换 .git/hooks/commit-msg
通过这个脚本编写去 .git/COMMIT_EDITMSG 中拿到commit的内容 然后进行commitMsg格式检测
二、进行preCommit之前的操作
在执行某个CMake的时候,设置一个命令add_custom_command
执行某个脚本文件(如node xx.js、python xx.py)
这个脚本文件会将 index.js 复制到.git/hooks命名为pre-commit,将commit-msg.js 复制到.git/hooks命名为commit-msg
(不建议使用build.sh文件 因为本地编译的时候 不一定会跑这个脚本文件)
.git/hooks/pre-commit 常用配置
1 先检查python环境 然后获取config文件 如哪些需要过滤的路径之类的
2 再执行 git diff --cached --name-only --diff-filter=ACM -- 得到state暂存区的文件路径
然后进行路径过滤(config文件配置的过滤目录)
3 文件命名检查 (rule: '^[a-zA-Z0-9_\\.\\-@\\+]+$')
4 拼写检查 (dict.txt) 纠正英文拼写错误
5 禁用词检查 防止使用某些不该使用的方法或者一些禁止的词语
6 cpplint检查 执行cpplint.py文件
.git/hooks/config
用于给pre-commit文件设置一些配置 如命名规范、检查算法
git commit -n(等价于–no-verify) 则不会执行pre-commit和commit-msg
// 打印字符串在某个文件的某行
git grep -n "字符串"
mac:
1 brew install git-lfs
2 拉取你的远端代码
3 在你的git仓库中 执行
git lfs install
若报错:
Error: Failed to call git rev-parse --git-dir --show-toplevel: "fatal: not a git repository (or any
可以先执行 git init 创建.git文件
1 推送大文件
告诉lfs需要管理的大文件,比如model.pb,运行命令git lfs track model.pb
将管理文件.gitattributes添加入git仓库git add .gitattributes
将大文件添加入git仓库,然后和其它添加方式一样
2 克隆有大文件的仓库
git lfs clone -b xx xxxxxxx
改密码
打开凭据管理器 ,在普通凭据找到你的GIt地址,修改密码即可
查看日志
可以获取到某个commit的SHA-1值
可以查看这个commit相对于上一个的代码变动
查看某个版本和另一个版本的差异
右键 TortoiseGit->与上一版本比较差异
可以通过版本的SHA-1值或者 Head指针 去进行不同版本的差异比较
常见问题:
1 The drive or UNC share you selected does not exist or is not accessible. Please select another
解决:将旧版本的git卸载了 再以管理员身份运行git安装程序
fatal: refusing to merge unrelated histories
原因:Pull远端的origin和本地的origin不同 如github上新建了一个仓库 然后本地也建立了一个
Git会避免你操作失误提醒你
解决:可以用git pull url branchName --allow-unrelated-histories确认
然后会有个让你输入为什么这样操作的记录 以方便后来回忆
2
env: node: No such file or directory
每次 commit,都要先自动运行一个node脚本,运行通过才会提交。提交的工具没有相应的环境运行不了该脚本。
可能是sourcetree的问题 通过手动输入git commit -m message 命令去上传试试 否则就得配置node和node环境
3 gitclone的时候 Failed to connect to xx.xx.com port 80: Connection refused
可能是用户改了密码 本地的密码没改 可能是ssh认证失败
加上用户名和密码
git clone -b master http://你的用户名:密码@xx.xx.com
4 Another git process seems to be running in this repository
解决:
1 删除.git/index.lock
2 删除.git/MERGE_RR.lock
参考:
http://blog.jobbole.com/78960/
http://1ke.co/course/194