git常用操作
git可以与tig配合使用,tig - text-mode interface for git
一. 简述
1. git索引
Git和其他版本控制系统的主要差别在于,Git只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异。
在保存到Git之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。这项特性作为Git的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git都能立即察觉。
Git使用SHA-1算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1哈希值,作为指纹字符串。该字串由40个十六进制字符组成,看起来就像是:
dbd4c2f121be08e514828f2533687b145a6e16dd
Git的工作完全依赖于这类指纹字串,所以你会经常看到这样的哈希值。实际上,所有保存在 Git数据库中的东西都是用此哈希值来作索引的,而不是靠文件名。
2. git状态
对于任何一个文件,在 Git 内都只有三种状态:
>>已修改(modified)
>>已暂存(staged)
>>已提交(committed)
已修改表示修改了某个文件,但还没有提交保存
已暂存表示把已修改的文件放在下次提交时要保存的清单中
已提交表示该文件已经被安全地保存在本地数据库中了
二. 基础操作
1. 登陆gitlab注册
首次登录时必须使用用户邮箱生成ssh-key并在gitLab上注册,跟换计算机后需要重新生成并注册,可以注册多个计算机,但必须是使用同一(需确认)邮箱。
生成方法:
-
ssh-keygen -t rsa -C "user_mail@example.com"
一路回车,生成文件在~.ssh/id_rsa.pub里面,拷贝该文件内容在gitLab主页profilesetting--sshkeys--add ssh key中注册。
- cat ~/.ssh/id_rsa.pub
2. 设置全局变量
Git global setup:
git config --global user.name "user"
git config --global user.email "user_mail@example.com"
git config --global core.editor vim
3. 从仓库克隆工程
git clone git@192.168.1.1:user/project-demo.git
4. 创建仓库
Create Repository
mkdir u-boot
cd u-boot
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@192.168.1.1:user/project-demo.git ;创建远程仓库origin(git默认,可修改)
git push -u origin master ;master为origin库的分支:master。
;加上了-u
参数,Git不但会把本地的master
分支内容推送的远程新的master
分支,
;还会把本地的master
分支和远程的master
分支关联起来,在以后的推送或者拉取时就可以简化命令。
5. 上传文件
已从在库
Existing Git Repo?
cd existing_git_repo
git remote add origin git@192.168.1.1:user/project-demo.git
git push origin master
若是token方式提交,只需把原来的密码更化为token即可:
git push origin master
username
token
6. 设置.gitignore
.gitignore只能忽略原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交:
git rm -r --cached .
git add .
git commit -m "update .gitignore"
三. 常用操作
git status ;查看仓库状态
git log ;查看修改日志
git log filename ;查看filename相关的commit记录
git log -p filename ;可以显示每次提交的diff
git show <commit-hashid> ;显示某次提交的修改内容
git show <commit-hashid> filename ;显示某次提交的某个内容的修改信息
git diff ;显示工作区修改内容
git diff --cached ;显示暂存区修改内容
git diff HEAD ;显示暂存区修改内容
git add file ;添加修改
git add . ;添加多个文件修改
git checkout file ;撤销单个文件修改
git checkout . ;撤销多个文件修改
git commit ;提交暂存区修改,新页面添加详细注释
git commit -m "annotate" ;提交暂存区修改,添加简单注释
git commit --amend ;修改注释内容
git format-patch \<start-commit\>..\<end-commit\> ;提取patch
git format-patch -1 \<commit-SHA\> ;提取单次提交patch
git apply patch-file ;应用patch
git apply --check newpatch.patch ;检查patch
git branch ;显示本地分支
git branch -a ;显示远程所有分支
git branch branch-name ;创建本地分支branch-name
git checkout branch-name ;切换分支到branch-name
git checkout -b branch-name ;创建并切换分支到branch-name
git branch -d branch-name ;删除本地分支
git push <远程主机名> <本地分支名>:<远程分支名> ;推送本地分支或tag到远程,远程分支名与本地分支名相同时可省略
git push origin branch-name ;推送分支branch-name到远端
git push origin tag-name ;推送tag到远端
git push origin --delete branch-name ;删除远程分支
git push origin --delete tag <tagname> ;删除远程tag
git merge branch-dev ;合并branch-dev到当前分支,执行快进式合并,只保留单条分支记录
git merge --no-ff branch-dev ;合并branch-dev到当前分支,保留之前的分支历史,可更好的查看分支历史
git cherry-pick <commit id> ;选择一个分支中的一个或几个commit(s)来进行再次提交(到当前分支)
git cherry-pick <start-commit-id>..<end-commit-id>
注:当执行完 cherry-pick 以后,将会生成一个新的提交;这个新的提交的哈希值和原来的不同,但标识名一样;
git reset commit1 ;撤销到某一次commit上,commit后的提交修改存在(软撤销)
git reset --hard commit1 ; 撤销到某一次commit上,commit后的提交修改不存在(硬撤销)
问题:
本地远程分支存在,而远程仓库已没有该分支,此时运行删除远程分支操作就会报错:
error: unable to delete '…': remote ref does not exist
应使用命令删除(或同步)远程分支:
git fetch -p origin
The fact that refs/remotes/origin/my_remote_branch exists in your local repository does not imply refs/heads/my_remote_branch exists in the origin remote repository.
Do git fetch -p origin to make refs/remotes/origin/my_remote_branch go away if it's already deleted in origin. The -p option tells fetch to delete any tracking branches that no longer exist in the corresponding remotes; by default they are kept around.
https://stackoverflow.com/questions/10292480/when-deleting-remote-git-branch-error-unable-to-push-to-unqualified-destinatio
四. 多人协作/远程分支
1. 当你从远程仓库克隆时,实际上git自动把本地的master分支和远程的master分支对应起来的,并且远程仓库的默认名称是origin。
git remote -v ;查看远程仓库情况
2. 默认情况下通过git clone拷贝到本地的分支只是master分支,要获取其他分支可用命令:
git checkout -b dev origin/dev
现在可以在dev分支开发了。
3. 推送分支
如果直接在master分支开发,可直接推送到master。
git push -u origin master
一般情况下都是在单独分支上开发,开发完成后推送本地分支到远程,然后再合并分支到master上。注:一般情况下,master分支是没有推送权限的,需要审核,防止错误推送。
git push origin dev
4. 下拉分支
若开发分支由多人维护,需要经常下拉分支以同步代码。
git pull ;下拉当前分支
有时下拉失败,会有提示信息。如"no tracking information",没有指定本地dev分支与远程origin/dev分支链接时
git branch --set-upstread dev origin/dev
5. 多人协作工作模式
》git push origin branch-name推送自己的修改;
》推送失败,则因为远程分支比你本地更新,需要先用git pull试图合并。
》如果合并有冲突,则解决冲突,并在本地提交;
》没有冲突或解决冲突后,用git push origin branch-name推送就能成功。
6. 合并分支
git merge branch-name
合并指定分支branch-name到当前分支
若合并有冲突,会有相关提示信息,或执行git status会显示冲突的文件,解决冲突后可以再合并(merge)。
五. 使用问题
1. 从一个github上下载新仓库,上传到另一个github上时,需要先git init;
然后 git remote set-url origin git@github.com:username/projectname.git
(原来已有git,需更新原来origin地址为新工程地址)。
2. 删除文件后,出现如下信息,但删除的文件已不存在
Changes not staged for commit
运行命令:git rm deletefile.name
这样以后就不会出现在未跟踪文件清单中了。
3. Your branch is ahead of 'origin/master' by 3 commits.
You get that message because you made changes in your local master and you didn't push them to remote. You have several ways to “solve” it and it normally depends on how your workflow looks like:
-
If you work in another way and your local changes should be pushed then just
git push origin
assuming origin is your remote
-
If your local changes are bad then just remove them or reset your local master to the state on remote
git reset--hard origin/master
4. git不能上传空目录和设备文件:目录和设备文件不能完成校验。
git使用命令校验: sha1sum console,目录或设备文件校验报错。
六. 嵌入三方库
需要时候开发要基于其他开源库,此时应该submodule来管理三方库,以使三方库的可追踪和及时更新。
七. git tag应用
git中tag就是一个标签,一个快照,不能修改它的代码。如果要在tag代码的基础上做修改,需要一个分支:
git checkout -b branch_name tag_name
这样就可基于此tag修改内容了。
其实要取得不同的branch的tag,只需要在相应的分支上打tag就行了。这样的tag就唯一对应了不同的分支。例如,你在master上打了tag为v1,在某个branch上打了tag为v2,则你取出v2代码的时候,自然就是对应的branch分支了。
git tag常用命令如下:
1. git tag ;显示本地标签
2. git tag v1.0 ;基于本次commit创建标签v1.0
3. git tag v0.9 f52c633 ;为commit id为f52c633打标签v0.9
4. git show v0.9 ;显示标签信息
5. git tag -a v0.1 -m “message” 1094add ;-a指定标签名,-m指定说明文字
6. git tag -d v0.1 ;删除本地标签
7. git push origin v1.0 ;推送tag
8. git push origin --tags ;一次性推送全部尚未推送到远程的本地标签
9. git push origin :refs/tags/v0.9 ;删除远端标签
10. git tag -l | xargs git tag -d ;删除所有本地分支
11. git fetch origin --tag ;远程拉取所有tag
12. git ls-remote --tags origin ;查询远程tags
八. 同步更新fork仓库
github上fork的仓库,当原始仓库更新时,如果同步更新本地仓库?参考:github如何更新fork的代码
九. rebase更新推送仓库
上面介绍的都是基于merge更新仓库,rebase提供了一种线性提交的方式。
git clone repo
git checkout origin/master -b fix_bug
git add bug_files
git commit -m "fix bug for files"
git fetch --all --prune //拉取最新code
git rebase origin/master //保证提交的code基于主干
git push origin fix_bug // push本地分支到主仓库
==>获取到merge request url,复制web browser打开即可提交申请。
十. 从一个git仓库内迁移分支代码到另一个git仓库,保存之前仓库的提交记录
第一种需求方式
如果A是已有仓库,B是新建立的空仓库。(如下操作,提交记录也会带到新仓库里)
1、在本地拉一下(git clone)A仓库的代码,或者是 git pull 下最新的代码。 2、git remote # 查看本地连接的有哪些 远程仓库,默认是 origin 3、git remote add origin2(这个名字随便起) master # 这里是在本地添加一个新的远程连接 4、git remote set-url origin2 B仓库的地址 # 这里是新加个远程连接 设置上url地址 5、在A的本地仓库 git push origin2 dev:master # origin2 是你想push上哪个远程库,dev 是你想push哪个分支,master 是push到远程的哪个分支。 这个命令执行以后要输密码,记得是新仓库的密码。 6、设置默认提交仓库, 将本地的分支和远程分支做关联,比如master分支 git branch --set-upstream-to=gitlab/master ,其他分支照此办理。
第二种需求,推送时,将B仓库的分支改为Master名称,而非A仓库的分支名称
1、克隆 A 仓库:首先,克隆 A 仓库到本地。使用以下命令: git clone <A仓库URL> 2、进入 A 仓库目录:使用以下命令进入克隆的 A 仓库目录: cd <A仓库目录> 3、查看 A 仓库的分支列表:使用以下命令查看 A 仓库的所有分支: git branch -a 这将列出 A 仓库中的所有分支,包括本地分支和远程分支。 4、切换到要推送的分支:使用以下命令切换到要推送到 B 仓库的分支: git checkout <要推送的分支> 5、重命名分支为 master:使用以下命令将当前分支重命名为 master: git branch -m master 6、添加 B 仓库作为新的远程仓库:添加 B 仓库作为新的远程仓库。使用以下命令: git remote add origin <B仓库URL> 这将添加一个名为 origin 的远程仓库,它指向 B 仓库 URL。 7、推送分支到 B 仓库:使用以下命令将重命名的 master 分支推送到 B 仓库: git push -u origin master -u 参数将设置 origin/master 作为本地分支的上游。
完成上述步骤后,A 仓库中指定的分支将被推送到 B 仓库,并在 B 仓库中命名为 master 分支。请确保在执行这些操作之前备份你的代码。
十一. 加速github访问
1 获取 GitHub 官方 CDN 地址展开目录
查询以下三个链接的 DNS 解析地址
- github.com
- assets-cdn.github.com
- github.global.ssl.fastly.net
记录下查询到的 IP 地址。
2 修改系统 Hosts 文件展开目录
打开系统 hosts 文件 (需管理员权限),路径:C:WindowsSystem32driversetc
在末尾添加三行记录并保存。(需管理员权限,注意 IP 地址与域名间需留有空格)
-
192.30.253.112 github.com
-
151.101.72.133 assets-cdn.github.com
-
151.101.193.194 github.global.ssl.fastly.net
3 刷新系统 DNS 缓存展开目录
Windows+X 打开系统命令行(管理员身份)或 powershell
运行 ipconfig /flushdns
手动刷新系统 DNS 缓存。
参考网址:
1. http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
3. git tag 标签完全用法(如何更好的管理你的分支)
5. 你真的懂git rebase吗? 简书
6. git中文教程