赞
踩
Git分为本地分支和远程分支,是一个分布式的版本管理系统,相对于svn的集中式管理,更加优越。
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
GIT不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
如果你是一个具有使用SVN背景的人,你需要做一定的思想转换,来适应GIT提供的一些概念和特征。
Git 与 SVN 区别点:
1、GIT是分布式的,SVN不是:这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
2、GIT把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
3、GIT分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
4、GIT没有一个全局的版本号,而SVN有:目前为止这是跟SVN相比GIT缺少的最大的一个特征。
5、GIT的内容完整性要优于SVN:GIT的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
Git可以以http方式拉取代码,也可以用ssh方式,后者可以用ssh key免密码登录。
git clone 拷贝代码
git status 当前代码状态
git log 提交历史
git add 文件加入git
git commit -a -m "comments" 代码提交并评论
git push 代码提交到远程分支
git pull 从远程分支拉取最新代码
git fetch FETCH_HEAD指的是: 某个branch在服务器上的最新状态
git branch xxx 创建某个分支
git checkout xxx 切换到某个分支
git checkout xxx.cpp 未提交状态下恢复文件,即revert
git merge master 合并当前分支到master
如果有submodule,clone代码时注意在地址后加“–recursive”,如:
git clone ssh://git@gitlab.zhb.domain:10022/zhb/zhb.git --recursive
在tortoiseGit上运行:
git submodule update
先显示提交的log
$ git log
commit 4dc08bb8996a6ee02f
Author: Mark <xxx@xx.com>
Date: Wed Sep 7 08:08:53 2016 +0800
commit 9cac9ba76574da2167
Author: xxx<xx@qq.com>
Date: Tue Sep 6 22:18:59 2016 +0800
回退到某个commit版本:
git reset --hard e377f60e28c8b84158
如果不加–hard,仅改变暂存区,并不改变工作区,这意味着在无任何其他操作的情况下,工作区中的实际文件同该命令运行之前无任何变化。即代码保留,回到 git add 之前。这通常在合并多个commit时使用。
如果加了–hard,就会完全回退到那个版本,不会保留修改的代码。
这个功能也可以实现强制把本地代码恢复成远程分支一样的,即恢复到远程分支的最新commit id。
强制提交:
git push -f origin master
(1)删除分支
删除本地分支
git branch -D br
删除远程分支
git push origin :br (origin 后面有空格)
(2)新建分支
新建并切换到本地dev分支
git checkout -b dev
本地分支与远程分支相关联
git pull origin dev
在本地新建分支并推送到远程
git checkout -b test
git push origin test
这样远程仓库中也就创建了一个test分支
git config --global user.name "张三"
git config --global user.email "zhangsan@126.com"
使用场景
当项目越来越庞大之后,不可避免的要拆分成多个子模块,我们希望各个子模块有独立的版本管理,并且由专门的人去维护,这时候我们就要用到git的submodule功能。
常用命令
git clone <repository> --recursive 递归的方式克隆整个项目
git submodule add <repository> <path> 添加子模块
git submodule init 初始化子模块
git submodule update 更新子模块
git submodule foreach git pull 拉取所有子模块
submodule如果更新错误,想要恢复原来的commit,用以下语句:
进入项目的目录,无需进submodule的目录
git submodule foreach git checkout 9b48ad26026b882d780ac94c9629cca467121ddd
如果是要恢复到某个分支,就在checkout后换成分支名
1.在自己的分支上,进入submodule目录,git checkout master
2.git pull & git fetch
3.退出submodule目录,git commit,git push
4.merge到master分支
产生原因:
有两个开发分支:zhb1,zhb2。两个分支都会对同一个文件做修改,这样在顺序提交合并到master分支时,就会产生冲突。
需要注意的是,只有对同一文件的同一行修改时,才需要手动解决冲突,如果修改的是不同行,git merge时,会自动处理。下面我们讨论的是对同一文件的同一行修改时产生的冲突。
有一文件:confict.txt
master分支上的内容是:
DECLARE_string(zhb1);
DECLARE_string(zhb2);
zhb1分支上新增一行,并修改第一行,内容变为:
DECLARE_string(zhb1==);
DECLARE_string(zhb2);
DECLARE_string(zhb3);
Commit,push到zhb1远程分支。
zhb2分支上删除第二行,并新增两行(新增的内容与zhb1分支不相同),内容变为:
DECLARE_string(zhb1);
DECLARE_string(zhb3==);
DECLARE_string(zhb4);
Commit,push到zhb2远程分支。
先把zhb1分支合并到master,并push,没问题。
再把zhb2分支合并到master,就会出现冲突:
提示自动合并失败,查看状态,出现both modified: confict.txt字样,表明该文件合并冲突了。
如果是在windows下的TortoiseGit工具查看该文件状态,文件会出现一个惊叹号:
这时,打开文件内容如下:
<<<<<<< HEAD
DECLARE_string(zhb1==);
DECLARE_string(zhb2);
DECLARE_string(zhb3);
=======
DECLARE_string(zhb1);
DECLARE_string(zhb3==);
DECLARE_string(zhb4);
>>>>>>> zhb2
<<<<<<<,=,>>>>>>>这三个标记是冲突的格式,
<<<<<<<到=是在当前分支合并之前的文件内容
=======到>>>>>>> zhb2是在其它分支下修改的内容
我们要做的是需要在这个两个版本中选择一个,然后把标记符号也要一起删除。
TortoiseGit提供了一个可视化的工具来编辑冲突。
修改编辑区,在下方的方框中编辑最终保留代码,保存标记冲突解决:
上面解决冲突的方式是,只保留以下两行,其他都删掉(注意行号前面的+、-号):
DECLARE_string(zhb3);
DECLARE_string(zhb4);
解决完冲突后,commit并push,整个流程结束。
git提交被拒绝,提示(non-fast-forward);
解决方法:
1. git fetch origin debug
获取远程分支debug的修改
2. git merge origin debug
合并远程分支debug
3. git pull origin debug
更新本地分支
这个时候提示文件有冲突,手动解决以下就可以了。
场景:多次commit合并为一个commit。
先reset到最老的一个commit id
git reset old_commit_id
注意:不能加–hard,加hard就直接回退了,不会保留文件修改了。
然后git status,查看修改的内容是否正确
接着git commit -m “combine commit id”
最后git push origin branch --force。
需要强制push代码。
更新本地master代码:
checkout master, git pull
切回自己的分支,合并master代码:
checkout mybranch ,git merge from master
将本地代码同步到远程分支:
sync push origin mybranch
git cherry-pick可以理解为”挑拣”提交,它会获取某一个分支的单笔提交,并作为一个新的提交引入到你当前分支上。
当我们需要在本地合入其他分支的提交时,如果我们不想对整个分支进行合并,而是只想将某一次提交合入到本地当前分支上,那么就要使用git cherry-pick了。用法:
git checkout mybranch
git cherry-pick 2dcdccd
意思是把commit id为2dcdccd的提交合并到mybranch分支上。
第一步: 在命令行中输入 git log src/main/main.c 得到该文件的commit 历史。
第二步: 复制需要回退版本的hash,在此假设我们回退到 d98a0f565804ba639ba46d6e4295d4f787ff2949 ,则复制该序列即可
第三步:checkout 对应版本。格式为 git checkout , 在此即为命令行中输入
git checkout d98a0f565804ba639ba46d6e4295d4f787ff2949 src/main/main.c
第四步: commit checkout下来的版本。 如: git commit -m “revert to previous version”
1. merge命令不会保留merge的分支的commit,直接合并两条线上的commit。
2. rebase会保留所有的commit,将所有的commit合成一条线。
合并两个分支,除了merge,还可以用rebase。
步骤:
git reset撤销当前分支所有修改,恢复到最近一次修改前干净的分支情况:
git reset --hard
git clean -fd
Git 压缩。基本思想是将多个连续提交合并为一个。
主要目的是将许多提交压缩为几个相关的提交。因此,这样做会使 git 历史看起来简洁明了。
有两种方法可以实现 Git 压缩:
git merge -squash 在合并时使用 -squash 选项
git rebase -i 作为用于压缩提交的交互式工具
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。