1.先决条件,代码是repo下来的,代码修改完毕
进入自己修改代码的模块下
git checkout -b sprdroid2.3_vlx_3.0 korg/分支名 (每个git仓库只用执行一次此命令,以后提交时不用敲此命令)
git status 查看当前的修改状态,红色的即为自己修改的文件
git add +想要提交的文件名或者git add . 添加所有的修改文件
git status 可以看到绿色的是提示要提交的文件名
git commit
git fetch korg
git rebase korg/分支名
repo upload (这一步必须在自己修改代码的大模块下) //或者用这个命令,不过待实验 git push ssh://[email protected]:29418/修改模块的name 此处有一个空格 HEAD:refs/for/分支名
再到gerrit上去看自己的change,会发现有变化了
这里以turnkey 2.3.5中一个bug提交为例,详细讲述第一次提交分支代码的步骤;(好像在服务器上提交更好,更少出错)
git checkout -b my_sprdroid2.3_vlx_3.0 korg/sprdroid2.3_vlx_3.0 (每个git仓库只用执行一次此命令,这里创建时跟踪的分支需要重点注意: 通过git branch -a 查看,每个仓库可能都不一样;例如:remotes/m/sprdroid4.4prime_3.10 -> korg/sprdroid4.4prime,则用sprdroid4.4prime )
git status
git add AudioSystem.h
git status
git commit //这里按照commit模板填写,必须要bug号;git升级后需要先crtl+x 然后 y 然后直接回车就行,不用选格式
git fetch korg //这一步貌似不是必须的了
git rebase korg/sprdroid2.3_vlx_3.0 //这一步貌似不是必须的了
git push ssh://[email protected]:29418/platform/packages/apps/Mms HEAD:refs/for/sprdroid2.3_vlx_3.0 //或者在git commit之后直接敲 ” repo upload . “
2.第一次提交时需要配置commit 模板格式
2.1 将附件中的文件放到工作目录下(注意把文件名改成.gitmessage) 即: ~/
2.2 随便进一个git仓库
git config --global commit.template ~/.gitmessage 以后commit时就会按照此模板填写
3.第一次使用需要在gerrit上添加密钥
gerrit网址 http://review.source.spreadtrum.com/gerrit/#/
在my 下面, 注册邮箱,注册后会在邮箱里收到认证链接; 然后在ssh里添加密钥,把自己电脑中的.ssh里的id_rsa.pub里的内容add上去
4.一些常用操作
【修改commit message】:就是commit时,写的bug nuber,root cause这些东西 ;些commit时也可以自己手动加一行changeid,这样就不会生成新的提交了,而相当与覆盖掉了之前的那次提交。
git commit --amend
【撤销最近一次提交】:~后面的数字
git reset --hard HEAD~1 撤销commit操作,同时还原代码
git reset --soft HEAD~1 撤销commit操作,但保留之前的修改 (当提交错误时使用,然后会提示use "git reset HEAD ..." to unstage ;将待提交状态更改无状态后,然后git add 再次提交即可)
git reset --hard HEAD 还原代码,重要(有时候最新版本删掉了某些文件,结果本地文件变成untracked, 需要删掉这个文件再同步)
【同步代码】
repo sync 这样会把所有分支的所有仓库都给同步了
repo sync . 这个是把当前目录下所有文件都给同步最新了
git pull --rebase 如果本地建立了远程分支,可以过此命令只同步当前仓库
【回退到某一时刻的提交,即版本回退,很有用】
git reset a9b0b4a295a35a7d8f4778d51ea0567c6296e9a4 //后面即是commit的id,非change ID;通过git log看
git checkout .
【提交后发现需要再修改一下】
之前已经有一个提交了,现在发现要再改一下,懒得abandon,可以修改完毕后,add后直接--amend,然后changeid 写之前的那次提交changeid,然后push上去,就可以用新的提交把之前那个给偷偷覆盖掉了
【提交冲突,仅限于把之前的提交再在新版上提交一次】
cd kernel //到待提交的仓库目录下
git fetch ssh://[email protected]:29418/kernel/common refs/changes/98/91898/1 && git checkout FETCH_HEAD //去自己的gerrit上取checkout 命令,然后在当前仓库下运行
git log //查找当时提交的commitid
git cherry-pick 7672803f962e32f95f6908f223e48fb5a75dcf1b //将自己的提交放到服务器的最前
//貌似只用执行下面两步就行
git pull --rebase //将服务器上最新代码取到本地,相当与拉代码
git push ssh://[email protected]:29418/kernel/common HEAD:refs/for/sprdlinux3.10 //此时再push一把即可
【把某个提交取到本地,即cherry-pick】
git fetch ssh://[email protected]:29418/kernel/common refs/changes/94/111494/2 && git cherry-pick FETCH_HEAD
repo forall -c 'git clean -f -d' ; repo forall -c 'git checkout -- .' ; repo sync ---清除所有仓库中修改文件 和中间文件 再同步代码
repo forall -c 'git checkout -b 本地分支名 要跟踪的远程分支名' 为所有的仓库创建分支 repo start my_branchname --all
git branch 本地分支名 //切换到本地分支名
git fecth korg //更新当前分支的代码
若只是单纯撤销修改:git checkout -- src/com/android/contacts/ViewContactActivity.java (修改的文件名)
若感觉问题复杂,repo sync,将文件恢复和服务器一样
【查看版本树】
git branch -r
【显示版本间的代码差异】
git log -p
【仅显示指定作者相关的提交】
git log --author=yingmin.piao
【列出所有包含hotfix字样的提交信息说明的提交记录】
git log --grep=hotfix
【版本切换】(只换某个仓库)
现建一个本地分支名保存当前分支
git checkout -b my_sprdroid4.4prime_3.10_tshark_dev korg/sprdroid4.4prime_3.10_tshark_dev //第一次用korg/sprdroid4.4prime_3.10_tshark_dev时执行
git checkout my_sprdroid4.4prime_3.10_tshark_dev //切换到korg/sprdroid4.4prime_3.10_tshark_dev分支上
要切回来则 git checkout my_sprdroid4.4_3.10_tshark_dev //切换到korg/sprdroid4.4_3.10_tshark_dev分支上
【提交代码时发现没有先本地建分支】
git stash 放到缓存里
git checkout -b sprdroid2.3_vlx_3.0 korg/sprdroid2.3_vlx_3.0 //本地建分支
git stash pop 从缓存弹出
2. 分支切换保存修改的code
git stash save "09-21-17:47" //将修改压栈里,并标记为"09-21-17:47"
git checkout 分支A
git stash list
git stash apply stash@{1} //切出去再切回来时,可以通过此命令,将之前save的stash 导出来。
git stash drop stash@{0} //这是删除第一个队列
git stash clear //这是删除整个栈里的队列
3. 提交
git checkout -b my_master origin/master
git push origin HEAD:refs/for/master
git reset --hard 04e55ffabbfa1f6a59b2b6514ad3f6eeeb40e414 //commit ID,回退代码到这一时刻
git branch -vv //查看本地分支信息
git diff | ./scripts/checkpatch.pl //检查代码
//git push报没权限错误时, 用 --no-thin
! [remote rejected] HEAD -> refs/for/phoenix-rom (n/a (unpacker error))
git push origin HEAD:refs/for/phoenix-rom --no-thin
"git push --no-thin
" actually disables the "thin pack transfer" optimization.
4. 回退
git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销
作为一次最新的提交
* git revert HEAD 撤销前一次 commitgit revert 0818badf6882ea2664a205bc8ef3a85425bb2537
*git revert 0818badf6882ea2664a205bc8ef3a85425bb2537 //撤销某一次commit
5. 看记录
读内核 tig blame 加 git log -S 必须熟练使用
6. git apply --reject sample.patch
這樣 git 會把 patch 檔中可以合進去的 hunk 加進去,剩下的放在 *.rej 中,* 是對應的檔名。所以到目前為止,有稍微往前一點了,再來就是看 *.rej 裡的 change 要怎麼加
7. 关于refs/for/ 和refs/heads/
这个不是git的规则,而是gerrit的规则,
Branches, remote-tracking branches, and tags等等都是对commite的引用(reference),引用都以 “refs/……”表示. 比如remote branch: origin/git_int(=refs/remotes/origin/git_int), local tag: v2.0(=refs/tags/v2.0), local branch: git_int(=refs/heads/git_int)…
简单点说,就是refs/for/mybranch需要经过code review之后才可以提交;refs/heads/mybranch不需要code review。
8.代码更新 git pull = git fetch + git merge
$git branch -a
* (no branch)
remotes/m/sanfrancisco -> smartisan/mol/h2-rom-1.0.2-20210721
remotes/smartisan/mol/h2-rom-1.0.2-20210721
$git checkout mol/h2-rom-1.0.2-20210721
$git remote -v
smartisan ssh://gerrit-mirror/qualcomm/platform/frameworks/base (fetch)
smartisan ssh://smartisan/qualcomm/platform/frameworks/base (push)
//这样即只更新当前仓库的 mol/h2-rom-1.0.2-20210721分支, 如果是git pull --rebase则会把所有分支都下载下来。
$git pull smartisan mol/h2-rom-1.0.2-20210721
=======================repo使用===============================
1.repo forall -c git git reset --hard HEAD 丢弃修改
2. 回退代码到指定时间 , 前提代码git 历史提交都下载下来了
repo forall -c 'commitID=`git log --before "2023-06-17 00:00" -1 --pretty=format:"%H"`; git reset --hard $commitID'
======================SVN使用=========================
1.下载svn服务器代码
svn checkout http://svn_ip/code_path
如果本地已创建code_path,则使用如下指令直接下载svn服务器到当前目录(加点)
svn checkout http://svn_ip/code_path .
2.查看本地code的svn地址及其他svn信息
svn info
3.svn帮助文档
svn help
4.更新本地code
svn up
5.查看本地文件与服务器是否有不同的文件
svn st
其中,M表示本地有修改,C表示本地与服务器有冲突,A表示本地新增文件尚未提交,D表示本地删除的文件尚未提交,其他的标识自行百度
6.比较本地文件与服务器差异
svn diff //列出所有不同文件
svn diff test.c //列出test.c与服务器之间的不同
7.增加本地文件,并准备提交服务器
svn add test.c //将test.c文件增加到本地svn
svn add folder //将folder目录及里面所有文件都add到本地svn
svn add folder --force //强制add
8.提交本地修改到服务器
svn commit -m "why commit" // 提交所有本地与服务器差异的文件
svn commit -m "why commit" test.c //仅提交test.c修改的文件
9.冲突时,放弃当前修改(最后的点不可忽略)
svn revert -R . //放弃本地所有不同文件
svn revert test.c //放弃一个本地文件的修改
10.svn up以后,本地存在冲突文件
会列出这样几个文件:
test.c //合并冲突的版本
test.c.mine //本地的版本
test.c.r001 //本地修改基于的服务器版本
test.c.r002 //服务器当前最新版本
可以查看test.c,确认差异点;
想直接覆盖服务器最新版本,直接把其他文件全部删除,将test.c.r002改名为test.c即可。
想直接用本地的提交,删除其他文件,将test.c.mine改名为test.c即可
11. 回退版本
// 放弃当前修改
svn revert -R .
更新至某个版本, 也即回退至某个版本
svn update -r 版本号
12 取消之前的add 等
svn revert --recursive example_folder
13 强制添加
svn add . --no-ignore --force
14. 打patch
因此,推荐大家使用git的format-patch和am命令进行生成patch和打patch,用此方法获得的patch其实就是commit里提交的code修改以及commit信息。有如下好处:
1. 对于git这种以project为单位的修改,尤其是涉及到多个文件夹下的多个文件的改动时,非常方便,能够记录所有的改动(添加,修改,删除文件等)
2. 可以保存commit信息。
3. 能够灵活的获取patch。可以获取任意两个commit之间的patch集。
使用方法(直接给一些examples):
git format-patch
$ git format-patch HEAD^ #生成最近的1次commit的patch
$ git format-patch HEAD^^ #生成最近的2次commit的patch
$ git format-patch HEAD^^^ #生成最近的3次commit的patch
$ git format-patch HEAD^^^^ #生成最近的4次commit的patch
$ git format-patch
$ git format-patch -1
$ git format-patch
$ git format-patch --root
git am
$ git apply --stat 0001-limit-log-function.patch # 查看patch的情况
$ git apply --check 0001-limit-log-function.patch # 检查patch是否能够打上,如果没有任何输出,则说明无冲突,可以打上
(注:git apply是另外一种打patch的命令,其与git am的区别是,git apply并不会将commit message等打上去,打完patch后需要重新git add和git commit,而git am会直接将patch的所有信息打上去,而且不用重新git add和git commit,author也是patch的author而不是打patch的人)
$ git am 0001-limit-log-function.patch # 将名字为0001-limit-log-function.patch的patch打上
$ git am --signoff 0001-limit-log-function.patch # 添加-s或者--signoff,还可以把自己的名字添加为signed off by信息,作用是注明打patch的人是谁,因为有时打patch的人并不是patch的作者
$ git am ~/patch-set/*.patch # 将路径~/patch-set/*.patch 按照先后顺序打上
$ git am --abort # 当git am失败时,用以将已经在am过程中打上的patch废弃掉(比如有三个patch,打到第三个patch时有冲突,那么这条命令会把打上的前两个patch丢弃掉,返回没有打patch的状态)
$ git am --resolved #当git am失败,解决完冲突后,这条命令会接着打patch
新建tag git tag v1.0
切换tag git checkout tag_name
列出已有tag git tag
删除tag git tag -d v0.1.2
远端删除 git push origin :refs/tags/
给指定的某个commit号加tag
git tag -a v1.2 9fceb02 -m "my tag"
或者
将tag同步到远程服务器 git push origin v1.0
详细见 git打tag - 简书
16. git branch
// 删除本地分支
git branch -d localBranchName
// 删除远程分支
git push origin --delete remoteBranchName
//新建本地分支
git checkout -b my_master origin/master
//切换分支
git checkout my_master