目录
【windows git fetch 时报错error: cannot lock ref 】
在上一条commit中追加新的修改(不生成新的commitid)
将分支A上的一个文件同步到分支B上(当前分支是B,然后同步分支A的文件到当前分支上)
拉取远程分支到本地,并关联起来(本地没有该分支代码)方法二:
gitlab API:
git pull和git fetch区别:
git pull和git fetch的区别(转) - 一_剑封喉 - 博客园
fetch 详解:
一般要用git fetch+git merge,因为git pull会将代码直接合并,造成冲突等无法知道,fetch代码下来要git diff orgin/xx来看一下差异然后再合并。
【设置git快捷指令】
打开本地家目录下的.bashrc,或者git config --global --edit打开.gitconfig,编辑:
alias gst='git status'
alias gl='git log --graph -5'
alias g='git'
alias gc='git commit -m'
保存并关闭文件。现在可以使用快捷指令:
gst 来代替 git status
gl 来代替git log --graph -5
gc来代替 git commit -m
【查看当前分支创建的源头,基于什么拉出的】
# 查看基于本地创建的新分支:git reflog show branch_name
# 查看在远程网页拉出的新分支:git reflog --date=local | grep branch-name
【git SSL验证关闭】
git进行clone或pull时,提示 SSL certificate problem: unable to get local issuer certificate
这个问题是由于git默认开启了SSL验证,关闭即可,解决方式:
Git config --global http.sslVerify false
执行以上指令,关闭ssl验证即可
【windows git fetch 时报错error: cannot lock ref 】
规避方案:可以将有问题分支本地删除,或者清理文件夹,重新clone
解决根因:在fetch目标分支的时候,本地已经存在该分支文件夹,导致fetch不下来,这命令在Linux执行没问题,差异仅仅是Windows和Linux导致的
Windows默认是大小写不敏感,可以通过修改大小写敏感来解决根因,如下:
git config -l查看 core.ignorecase=true,修改为false 或者git config core.ignorecase false
给git库文件添加权限(默认有读权限,添加写、可执行)
git update-index --chmod=+x file
# 例如: 给代码目录下所有sh脚本添加可执行权限
find ./ -name '*.sh' | xargs git update-index --chmod=+x
查看git提交记录文件列表
git show commitid --stat #查看某一次提交修改的文件列表
git log --stat #每次修改的文件列表, 及文件修改的统计
查看某个文件指定代码块的修改历史 git blame
git blame -L 3,5 file # 查看file的3-5行修改历史。
在上一条commit中追加新的修改(不生成新的commitid)
# (在上一条commit中,追加其他的文件修改,push到远程需要强制-f 方式)
git commit --amend --no-edit
# 变了hash值,但是message内容没有变化,最终只有一条commit
git commit --amend -m "new xxxxxxxxxxxx"
# 去掉--no-edit,即可修改message内容,同样只有一条commit
克隆远程已有分支到本地的做法:
第一种,传统标准的做法:
举例说明:将远程origin仓库的xx分支合并到本地的yy分支。
git fetch origin xx
git checkout yy
git merge FETCH_HEAD
# FETCH_HEAD: 是一个版本链接,记录在本地的一个文件中,指向着目前已经从远程仓库取下来的分支的末端版本。
第二种,直接使用pull命令,将远程仓库的目标分支合并到本地的分支:
git pull <remoterepo_name> <branch_name>
举例说明:将远程origin仓库的xx分支合并到本地的yy分支
git checkout yy
git pull origin xx
第三种:
是否可以先本地checkout远程目标分支,或者本地已经有了,先pull更新下来,然后将本地的两个分支进行merge不也可以吗?
答案是肯定的。
举个例子:
将远程origin仓库的xx分支合并到本地的yy分支。
git checkout xx
git pull # 如果本地没有xx分支的,这一步都可以不执行。
git checkout yy # 切换到yy分支
git merge xx # 将xx分支合并到yy分支 这一步可以加上 --no-ff 参数,即 git merge --no-ff
git fetch origin branch1
设定当前分支的FETCH_HEAD’ 为远程仓库的branch1分支,这种I情况下不会在本地创建本地远程分支,这是因为,这个操作是git pull origin branch1的第一步,而对应的pull操作,并不会在本地创建新的branch1
附加效果:测试远程branch1是否存在
将分支A上的一个文件同步到分支B上(当前分支是B,然后同步分支A的文件到当前分支上)
git checkout branch_A -- file ## file是相对路径
拉取远程分支到本地(本地没有该分支代码)方法一:
git fetch origin branch1:branch2
git checkout branch2
使用远程branch1分支在本地创建branch2,但不会切换到 该分支;
如果本地不存在branch2,则会自动创建一个branch2;
如果本地branch2存在,而且是'fast forward' 则自动合并两个分支。第一次push到远程之前,需要本地先关联一下
拉取远程分支到本地,并关联起来(本地没有该分支代码)方法二:
git checkout -b release_dev origin/release_dev
git push origin release_dev:release_dev
本地新建一个release_dev分支,并和指定的远程分支origin/release_dev关联起来,将远程release_dev分支拉去到本地,本地新建一个同名分支,二者关联起来
若拉取不成功,则执行git fetch先;第一次可直接push到远程,无需关联
本地创建好分支然后推送到远程:
git checkout -b my_branch
git push origin my_branch:my_branch
推送本地新建的分支my_branch到远程,冒号前是本地分支名字,冒号后是远程分支名,远程没有则会自动创建
git reset 用法:
如果git workspace凌乱,状态难以清楚恢复,可以尝试git reset commitid --hard,强制清理工作区
https://www.huaweicloud.com/articles/e3072119f707e0456aa07857ce34495e.html
Git reset a.txt 相当于git add a.txt的逆操作,如果a.txt是新建文件,则不起作用
git reset --hard [commit] # 工作区回退到某个commit的版本,并删除之后的版本内容
git reset <commitid> # 工作区回退到该次commitid内容,撤销add,但不删除改动代码
本地错误commit push到远程之后,回撤步骤:
假设本地提交场景:a->b->c->d
本地 git reset --hard HEAD~2
# 代码内容回退到版本b,版本b之后的本地内容都被删除了
# 也可以使用git reset ORIG_HEAD 回到版本d,本地版本d的内容恢复,重新修改代码,再次git add && git commit
git push origin branch --force #如果远程分支高于本地分支版本,执行强制推到远程
查看本地与远程分支和关联情况: git branch -vv
查看本地分支以及追踪的分支信息: git branch -av
查看本地和远程分支的最新版本指向: git remote -v
查看最近四次提交记录 git show-branch --more=4
diff对比工作区和暂存区;对比本地仓库和远程仓库
git diff # 不接参数:查看的是本地工作区修改的内容(add之前,查看改动内容)
git diff --staged # 查看本地已经暂存的文件和上次commit对比(在add之后,commit之前使用,查看本地add之后变化)
git diff dev origin/dev # 查看本地工作区和远程仓库对比(commit之后使用;git fetch origin master之后使用diff查看fetch下来的和本地代码区别)
git diff branch1 branch22 -- file_one #比较两个分支的某个文件的最新归档差别
只是删除历史commit中的一条内容
git reabase -i HEAD~5
# 会进入vi编辑界面,找到对应的commitid,将前边的pick替换为d(d就是删除该条记录的意思),然后:wq保存即可。
git push origin mybreanch --force # 需要强制推送
修改已经push了的commit信息
git commit --amend # 相当于撤销上次commit重新提交
# 进入修改界面,保存退出,强制提交入库
git push origin branch --force # 强推
正确使用merge和rebase:
GIT使用rebase和merge的正确姿势 - 知乎
如果远程没有该分支,本地创建新分支之后,想要推送到远程,直接git push不起作用,需要先关联set ...指令,之后可以使用 git push origin dev:dev将本地dev分支推动到远程dev分支
个人分支经常用rebase解决问题:
①利用rebase减少merge过程中复杂的commit信息,时间线统一
②本地分支是基于该主干延伸出来的一个个人分支,远程主干分支更新了,本地主干没有及时同步,用rebase将远程主干分支上新增的的提交在个人分支上重演一遍,然后--force推到远程,从个人分支merge到主干即可,简化提交历史不繁琐
git checkout develop && git pull
git checkout you_branch && git rebase develop
git checkout develop && git merge your_branch
# 个人分支上用rebase ;主干分支上用merge不用rebase
# 如果个人分支需要push到远程,因为rebase变基了,需要--force强制push
git rebase master
git push origin B1 --force
# 个人分支reabase其他分支之后,直接git push oring B1是失败的,因为使用reabase之后,master上的修改在B1分支上重演了一遍,相对于远程B1而言,本地仓库B1基地已经变化了,直接push是不行的,需要--force参数强制才能提交
远程分支版本高于本地分支代码
本地先fetch下来:git fetch origin dev
查看origin和本地区别:git diff dev origin/dev
确认无误后,合并一起,git merge FETCH_HEAD
或者直接git pull origin dev --rebase 用rebase的方式pull下来更新成远程最新代码
pull 用--rebase方式拉取代码
git checkout B1
git pull origin B1 --rebase
# git pull默认使用的是merge方式更新代码,有的时候会发现一笔 自己分支合并到自己分支的记录,pull代码时候,最好--reabase方式合并pull下来
重置工作区内容
每次修改,如果不用git add到暂存区,就不会加入到commit中
当你打乱了工作区的某个文件内容,想直接丢弃工作区的修改:
git checkout --file
将分支B的某一个文件替换到分支A上。
git checkout A # 先切换到A分支
git checkout B -- file # 注意:-- 前后是有空格,file是文件目录
不但改乱了工作区内容,还add添加到了暂存区了,想丢弃修改:
git reset HEAD file
git checkout --file
先有本地库,后有远程库,需关联远程仓库
git remote add origin git@repo.git
git push -u origin master
分布式版本系统的最大好处之一:在本地工作完全不需要考虑远程仓库的存在,也就是有没有联网都可以正常工作,而svn在没有联网的时候是无法干活的。git当有网络的时候,再把本地提交推送一下就完成了同步
HEAD-->master-->commit
一般来说,master是本地默认的分支名,它指向当前最新提交
HEAD指向一个分支,而且是当前的工作分支
也即:HEAD-->master-->commit
创建分支就是创建一个指向commit链的指针变量
切换分支就是对HEAD重新赋值,使它指向不同的分支指针变量
git cherry-pick:不同分支间的同步命令
在众多提交中选出一个提交应用到当前分支上,该命令需要一个commitid组为参数,过程相当于将该commit导出为补丁文件,然后在当前分支的HEAD上重放,形成无论内容还是提交说明都与之前一致的一个新commit
git cherry-pick 1122112
git push不会推送标签,除非使用 --tags
git push origin master --tags
删除分支:
删除远程:
git push origin :dev
git push origin --delete dev
删除本地:
git branch -d name
git branch -D name
tag操作
新建tag:git tag -a Tag1.1 -m "..." 或者 git tag v1.1 commitid
删除本地tag: git -d tag1.1
删除远程tag: git push origin :Tag1.1
列出所有tag: git tag show | git tag --list
推送tag到远程: git push origin Tag1.1
推送本地所有tag: git push orgin --tags
利用历史tag切换并修改历史内容,利用tag创建分支:
git checkout -b new_branch Tag1.1
git checkout master
git merge new_branch
git submodule用法:
Git Submodule使用完整教程 - lsgxeva - 博客园
比较归档版本之间区别,获取本次提交和上次提交的增量文件
git log mybranch ^master --pretty=oneline | wc -l
#上述指令获取从主干分支master拉出的个人分支mybranch提交的历史,从master checkout后,一共commit次数
git diff --name-only HEAD~4 HEAD
#再根据上边提交记录次数对比出哪些增量修改文件
①如果是个人独自分支上工作,git diff --name-only HEAD~4 HEAD即可
②如果多人共同分支上协作,先获取从checkout出新分支到本次push提交,一共多少次commit,然后根据commit次数获取修改的文件有哪些
特殊文件 .gitignore
其中写入的文件不会再被追踪。
①如果写入.gitignore的文件之前没有被提交过,那么包含.gitignore之后,该文件归档是不会被加入。
②但是如果以前某个文件是被追踪归档的,那么加入.gitignoew后,还要执行git rm -r -cached dirname/filename 将此文件从暂存区中删除,然后在提交,这个文件就不会被追踪管理了 执行完上边指令后,手动修改.gitignore文件,然后使用git status查看
查看提交历史,查看某一次commit内容
git log --oneline #一行呈现
git show commitid #某一次commit内容
git show commitid --stat #只展示所修改的内容列表
提交MR,源头分支和目标分支有冲突,解决方案。
如果基于目标分支拉出新分支后,新分支和目标分支都修改了同一个文件,源头分支修改完毕MR打算合入时,会提示冲突。
如何解决:
git pull origin test --rebase # 首先将源头分支test pull到本地
git fetch --all # 更新origin代码
git pull origin master # 将目标分支master pull到本地源头分支test上
# 会提示pull不成功,因为有冲突文件
git status # 找both modify的文件,就是冲突文件,打开冲突文件,找到<<<<< ====== >>>>>地方
# <<<<< ======之间的部分是源头分支test的修改,也就是本地分支的修改,这些内容还不在远程仓库中
# ====== >>>>>之间的部分是目标分支master代码也就是远程仓库的代码
# 确认保留正确代码,删除冗余的,:wq保存退出。
git add file
git commit -m "" #提交改动
git push origin branch # push 到远程,重新查看MR,冲突已被解决
Windows环境git clone时报错SSL certificate problem: certificate has expired
解决方案:这种问题,在windows下出现得频率高些。我估计主要是git本身就是基于linux开发的,在windows上,容易缺失一些环境。
git config --global http.sslVerify false