前言
有时一些场景忘记git相关一些命令,想用的时候临时搜索经常不全又耗时,写在这里方便唤起回忆
场景1:开始新建本地分支时未关联远程分支,后面使用命令关联上远程分支
1、从远端克隆仓库等所有东西到本地。
$ git clone git@github... //
2、创建本地分支,使用 git checkout -b或者android studio的可视化选项new branch from select是不会关联(或叫追踪)远程分支的。
$ git checkout -b local-develop //local-develop是本地分支名
3、关联当前本地分支和远程分支(名为remote-branch)关联
$ git branch --set-upstream-to origin/remote-branch local-branch //remote-branch远程分支名,local-branch当前本地分支名
2,3步使用这下面两个命令任意一个可以一步到位(创建本地并追踪远程),就没那么多事啦~
$ git checkout -b local-branch origin/remote-branch //local-branch当前本地分支名,remote-branch远程分支名
$ git checkout --track origin/remote-branch //直接使用远程分支名作为本地分支名
4、使用git branch -vv 关联上的会有远程分支名(蓝色)

5、若需要修改远程url 也就是origin的url使用 git remote set-url origin
$ git remote set-url origin url地址 //url地址是新的git地址
$ git remote -v //查看设置新的git地址是否成功
场景2:使用.gitignore与.git/info/exclude忽略.idea等文件夹和.img后缀文件
1.使用.ignore文件忽略上传文件
编写在项目工程中的.ignore文件达到忽略效果,.ignore会被上传到远程仓库,克隆此工程的其他开发者在使用git上传时也会忽略这些文件
规则:*通配多个字符,?通配单个字符,[]包含单个字符的匹配列表,!表示不忽略(跟踪)匹配到的文件或目录,配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效。
示例:忽略所有后缀位iml的文件,忽略local.properties文件 忽略.idea和build文件夹。
*.iml
/local.properties
/.idea/
/build
2.使用.git/info/exclude文件忽略上传文件
编写在项目目录下的.git目录下info文件夹下的exclude文件,区别于.ignore这是本地git配置文件不会上传到远程,只会忽略本地工程文件,其他开发人员不会拿到这个文件也就不会忽略你在上面编写要忽略的文件。
可以使用vim或者其他编辑器编写:
示例:忽略项目根目录下的所有xml后缀文件和local.properties
*xml
/local.properties
特别注意:.git/info/exclude不生效或者使用时机不对问题:对于提交到缓冲区的文件(也就是add后的文件)是不生效的,只对工作区未add文件(红色的文件)生效。已跟踪文件可以通过git rm -r --cached从缓存区去掉文件,也就不会跟踪上传了
场景3:git撤回撤销提交记录
前提搞懂4个概念:工作区,缓存区(暂存区,又叫stage或index,实际就是索引目录树),本地仓库,远程仓库。
git reset命令撤销:
git reset --hard <commit Id> 工作区,缓存区,仓库回退到此commit id的代码,都不保留此commit id之后的改动。
git reset --mixed <commit Id> (不带--mixed ,--hard或--soft默认是mixed),缓存区,仓库回退到此commit的代码,工作区保留此commit id之后的修改(缓存区修改会移动到工作区)。
git reset --soft <commit Id> 仓库回退到commit id的代码,工作区和缓存区保留commit id之后提交的代码
git revert命令撤销:
git revert <commit id> 此操作要求先提交或stash缓存区改动,所以revert前后缓存区会保持一样,仓库回退到commit id的代码,并且撤销作为一次commit操作记录到仓库,工作区会保留commit id之后的修改。
总结:经过试验--hard参数会吃掉文件,其他的不会
场景4:git提交代码conflict冲突解决
下拉合并远程代码,这时候涉及三种方式git pull和git fetch+git merge或git fetch+git rebase来合并服务器和本地代码,解决冲突后再次pull
git pull和git fetch + git merge 和git fetch + git merge三者区别和对比:
git pull:如果有冲突,pull后冲突并文件会在工作区,需要重新add和commit,会产生新的commit id;如果没冲突直接server覆盖本地。
fetch+merge: fetch先取远程代码,fetch是仓库到仓库,然后使用merge命令将仓库修改到工作区,如果有冲突要求手动解决冲突,冲突文件在工作区需要add到缓冲区再commit到仓库,会产生新的commitid,基本和git pull一样(网上说fetch+merge和pull的还有区别,待验证);没有冲突直接server覆盖本地。
fetch + rebase:fetch先取远程代码,再使用git rebase,有冲突会提示手动解决冲突,并且冲突文件需要add标记解决冲突,然后rebase --continue就可以push了,不会用到commit不会产生新的commit id,没有冲突直接server覆盖本地,base会使本地的提交在server更新的提交之后打乱时序
本地间的merge和rebase区别: 主分支有A提交,feature1 基于主分支有A--B提交,feature2 有基于主分支A--C--D提交,checkout 主分支,用merge feature1的提交,主分支变A--B,这之后分三种情况:
情况1、checkout 主分支,merge feature2的提交,就会生成新的merge提交E,并包含正确时间的A--B--E和A--C--D--E两条并行线提交
情况2、checkout主分支,rebase feature2的提交,不会生成新的提交E,但是B提交时间和hash会被修改成新的,变成 A--C--D--B一条串行线提交。
情况3、checkout feature2,rebase master的提交,不会生成新的提交E,但是C、D提交时间和hash会被修改成新的,变成A--B--C--D一条串行的提交。
所以:有冲突时候checkout到的那条分支使用rebase会改变当前分支的提交时间和hash,基本都是建议个人分支用rebase合并冲突,修改个人的提交记录没关系,master公共分支用merge避免修改公共的历史提交记录顺序
cherry-pick: 选取一个特定id的提交到新分支上,而不是整个分支的所有新提交,会在目标分支上创建新的提交
场景5:git仓库中添加git子模块
适用于多个不同项目中使用了同一个模块或sdk
$ git submodule add 子模块git地址 本地路径
添加后可以在项目中看到.gitmodules文件,点击进去看相关信息如下
[submodule "sdk"]
path = sdk
url = http://**********/sdk.git
父项目仓库clone下来后使用命令完成子模块的初始化-更新(也就是clone),不然项目中没有子模块代码
$ git submodule init
$ git submodule update
或者组合方式:
$ git submodule update --init --recursive