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

四. 多人协作/远程分支

参考:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013760174128707b935b0be6fc4fc6ace66c4f15618f8d000

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 Submodule简单使用 

使用Git 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的代码

git remote add upstream fork-origin-repo
git remote -v
git fetch upstream
git merge upstream/master
git push origin master   ;推送主分支
git push origin --tags   ;推送更新的tags

九. rebase更新推送仓库

上面介绍的都是基于merge更新仓库,rebase提供了一种线性提交的方式。

参考:你真的懂git 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 merge 操作合并分支会让两个分支的每一次提交都按照提交时间(并不是push时间)排序,并且会将两个分支的最新一次commit点进行合并成一个新的commit,最终的分支树呈现非整条线性直线的形式。
git rebase操作实际上是将当前执行rebase分支的所有基于原分支提交点之后的commit打散成一个一个的patch,并重新生成一个新的commit hash值,再次基于原分支目前最新的commit点上进行提交,并不根据两个分支上实际的每次提交的时间点排序,rebase完成后,切到基分支进行合并另一个分支时也不会生成一个新的commit点,可以保持整个分支树的完美线性。

十. 从一个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访问

通过修改系统 hosts 文件的办法,绕过国内 dns 解析,直接访问 GitHub 的 CDN 节点,从而达到加速的目的。不需要海外的服务器辅助。

1 获取 GitHub 官方 CDN 地址展开目录

打开 https://www.ipaddress.com/

查询以下三个链接的 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

2. https://git-scm.com/book/zh/v1/Git-%E5%9F%BA%E7%A1%80-%E8%AE%B0%E5%BD%95%E6%AF%8F%E6%AC%A1%E6%9B%B4%E6%96%B0%E5%88%B0%E4%BB%93%E5%BA%93

3. git tag 标签完全用法(如何更好的管理你的分支)

4. git 如何同步本地、远程的分支和tag信息

5.  你真的懂git rebase吗? 简书

6. git中文教程

posted @ 2016-03-18 16:14  yuxi_o  阅读(741)  评论(0编辑  收藏  举报