git使用及常用命令

git使用及常用命令

1.Git子模块

使用情况:例如Android系统代码和app之间可以使用这种submodule的方法来管理。

快速上手:

$ git submodule add url path/to/name 

$ git submodule init

$ git submodule foreach git pull

其它情况下submodule不适用,可以用subtree来代替。

2.同步一个COMMIT

$ git cherry-pick xxx

可以同步一个commit到本分支

3.Git打TAG

打TAG也就是发布版本

$ git tag -a v1.2 -m "version 1.4"

$ git push --tags

如果还不能理解可以到这里看看是linus是怎么给linux内核打的TAG,TAG看起来像什么:https://github.com/torvalds/linux/releases


4.查看status详情

$ git status

$ git ls -n

$ git add xxx

$ git diff --cached

这样可以在commit之前先看一下修改详情。


5.不产生无用的merge的同步

有这么一种情况,用一个分支专门同步代码提供商的代码的时候,如果一般的pull会不断的产生一个merge看起来会很烦,用下边的使用添加一个--rebase就不会产生无用的merge了

$ git pull --rebase origin master


6.关于stash

适用情况:做了修改后,还没有add commit等等后续工作,现在突然要切换分支做其它事情,默认情况下你在这个分支修改的代码会被带到切换过去的分支中。可以先把你修改的保存起来。这些修改可以再还原过来。

$ git stash -u

$ xxxx 随便你的操作

$ git stash pop

注意:-u是代表是也把添加的新文件(术语是未跟踪)也藏起来,一般是要有这个u的。


7.恢复一个COMMIT

如果一个COMMIT你不想要了,想要去除,可以考虑使用以下的方法;

$ git revert xxxx

这个就可以去掉这个COMMIT的改动,这个是明式的去掉,如果你又后悔了,还可以再次恢复。


8.安装最新Git版本

能轻易安装的一般不会是最新的,用apt-get install便是如此。下面用离线的方式安装Git。

a先到https://github.com/git/git/releases看最新版本,然后复制链接。红色随具体版本变化。

$ apt-get remove git # 卸载现有

sudo apt-get install libssl-dev libcurl4-openssl-dev libexpat1-dev #安装必要的库

$ wget https://github.com/git/git/releases/tag/v1.8.4.3 (链接地址)

$ tar xvzf v1.8.4.3.tar.gz

$ cd git-v1.8.4.3

$ make prefix=/opt/git all

$ make prefix=/opt/git install

$ 添加/opt/git/bin到环境变量中 /etc/environment中,或者其它。


9.安装subtree 

$ git clone https://github.com/apenwarr/git-subtree

$ cp git-subtree/git-subtree.sh /opt/git/bin/git-subtree

关于使用的subtree的几个帖子:

《使用git subtree集成项目到子目录》

《一个成功的Git分支模型》

建议尽量使用命令行操作,subtree用起来还是不爽

10.Git之本地忽略

这个分同种情况:a是本地永久忽略,效果的gitignore一样,只不过不适于写到gitignore中而已,可以自己建立一个本地独享的gitignore,然后git config --global core.excludesfile  文件的绝对路径,也可以直接将本地要忽略的文件添加到.git/info/exclude中。不过上述都是针对没有跟踪的文件来说的,如果文件已经被跟踪了你如果在本地想要忽略它的改动,就不能使用以上的方法了。这正情况b。通俗地讲比如一个编译Android的脚本在其它电脑上都是使用的-j32来编译的,但是你的电脑配置没有别人的好,不能开到-j32,但是这个脚本是已经跟踪过的,你修改了就会在每次的git status中看到。对于这种情况Git有一个忽略改动的方法:

$ git update-index --assume-unchanged /path/to/file       #忽略跟踪

git update-index --no-assume-unchanged /path/to/file  #恢复跟踪


之后你在本地修改/path/to/file这个文件,Git也不管它了。就实现了本地忽略。

11.Gitlab用户头像的问题

如果装的Git服务器是GitLab的话,是可以使用用户头像的,GitLab管理头像的一般方法是用gravatar,这一点和github一样,是关联email地址的,先在上边注册一个账户,上传一个头像并关联某一个邮箱,Gitlab或者Github会自动去gravatar上拉取你的个人头像。

12.Git打包源码

对Git管理的源码进行压缩打包,如果使用tar xvzf xxxx.tag.gz xxxxx的话并不是一个很好的选择,因为会将.git/目录下的中间文件全部压缩,如果只想要某一个版本的源码。Git提供了archive.它会给打包一份纯净的代码。当然这个只适用于发部一个版本的源码,而不是备份Git管理的整套源码。

$ git archive xxxx

xxx代表SHA-1 Hash值。

13.Git反向打补丁

一套没有管理有源码,中间有功能A,且也有功能A的补丁文件,可以使用补丁文件进行反打补丁来实现去掉功能A。

$ git apply -R

注:只是收集,还没有完整测试这里。

13.关于Git服务器选择和安装

选择建议GitLab,安装我参考加总结这几个帖子:

1.《 gitlabhq / doc / install / installation.md 》根据国情为官方的安装方法添加了说明的安装文档。

2.《 在 Ubuntu 12.04 上安装 GitLab6.x》一个对安装过程打印信息都记录的安装文档,安装过程中可以对比安装过程。

3.《重设MySQL root密码》中间遇到的问题MySQL密码找不到了,这篇文章给了答案。

14.合并commit

1.《使用git合并多个提交

2.《git如何合并只有两个commit到一个?》

15.Git只clone最新版本代码不要.git目录

这个也是在群中出现了问题,我曾经也有过这样的需求,想法是好的,但是理解是错误的。如果只要最后一个版本的代码,而不要.git目录中的东西,有办法:

git clone --depth=1 git://someserver/somerepo dirformynewrepo

rm -rf !$/.git

但是这又说明不是要参与开发的,是使用的。使用一般是要使用代码开发最新发布版本,如果只要最新的提交版本是没有用处的。因为它不是稳定的。这样就引入了发布版本这一说明,Git中是打Tag,一个tag是一个版本,可以以刚才的需求去找最后一个tag版本。github上是可以直接下载某一个tag版本的。如果要用git clone来完成,会复杂一些。现在的github是结合了web的,例如github或者是自己搭建的gitlab都是可以直接从web上下载指定的tag版本。而没有用于版本控制的.git目录。


16.关于pull和merge

都在提倡添加--no-ff选项。

17.删除子模块-解决子模块自动找上门的问题

    也许你并不想要用子模块,但是有时它会自动找上门,那么你要了解一下怎么去除它了。怎么个自动上门,且听我慢慢道来。
    在项目A中,如果用git clone了另外一个项目B,或许你只是想把项目B的代码添加到项目A中,但是这时执行git status/add的时候会发现项目B中的代码,并不会被添加,也就是说不能被跟踪。这是为什么呢,这里因为会自动将项目B做为了子模块管理,就是因为它是一个包含.git目录的完整的工程。解决这个问题有同种方法:
1.在clone项目b的后立即将项目B中的.git目录删除
2.git rm --cached path/to/B
然后再执行git status/add 之类的命令就会可以正常的跟踪了。

18.恢复一个文件到之前的某个提交

    这个种情况一般是出在某个bug解决后整理规范代码的时候,解决这个bug的时候可能添加了不少的调试代码,最后解决后,有些调试信息只为了了解代码流程,对以后并没有保留的意义,所以就要将其恢复开始解决这个bug之前的提交。xxxxx代表开始解决这个bug之前的一个提交的哈希码。
对于已经跟踪的文件:
1.git reset xxxxxx path/to/file
2.git checkout path/to/file
对于没有跟踪的文件:
1.git rm path/to/file

19.合并时只产生合并提交

    还有其它说法:合并时不合并历史;合并时将所有commit合为一个。
git pull --squash another
    话说一般用于master分支,像linus的linux内核一样。

更多信息见《Git merge no history commit》《git merge –squash介绍》

20.关于GUI Clients

这里《GUI Clients》。

21.git pull 前简单审查

情况是这样的:本人管理的是develop分支,其他人管理的他们自己的分支。所以应该每次改动的都应该是package/apps下的文件,但是有一种情况是我担心他们会不小心改到系统代码并提交了。在合并之前查看都改了哪些文件。这样就能有效地防止误修改。

和老友沟通后,得出以下结论:
1.让他们添加本地忽略,忽略他们一定不会改的目录。
2.在每次合并代码的时候,看一下每个分支都修改了哪些文件,有没有系统文件被修改
3.使用grrit。
4.先git fetch 再merge。
最后选择了第二种。因为git pull后,提交的时候会显示出这次合并代码都有哪些修改。

22.Gitk 不错的查看Log的工具

23.Git遇上代码规范

Git遇上代码规范会有些事情要处理好,这里写先写个经典的:

1.检测自己要提交的代码中有无table

一般多人开发的程序中不准使用table代替空格的,以下是GoogleJava代码规范(中文)中的截图:

 

所以在提交代码前自检一下自己代码中有有无table是很有必要的。

$ git diff | grep -P “\t” | grep “+”

如果tab已经存在,这里有很好的解决方案,所以项目代码不要急于commit前期工作很重要。

24.You are in the middle of an am session.

$ git status

On branch hardware

You are in the middle of an am session.

  (fix conflicts and then run "git am --continue")

  (use "git am --skip" to skip this patch)

  (use "git am --abort" to restore the original branch)

 

nothing to commit, working directory clean

对于这个情况,我是在接手一个别人的仓库的时候遇到的,我目前没有更好的方法,也不知道做了哪些事情,我采取的是 重新clone一份代码。


25.Git镜像-简易仓库

    working tree/bare tree/remote tree

    一般情况下没有这个需求,做镜像一般是中转服务器。

    $ git clone --mirror xxx.git

    执行以上命令将会clone一个裸版库,正常clone下来的是代码版本的库。前者不是用来编辑的,它本身是一个Git服务器上的仓库,可以供客户端进行pullpush。这其实也算是一个简易的Git服务器了。

在这个裸版库中,没有pullpush,有的只是

$ git remote update

会和远程库更新为远程仓库的内容。如果裸版仓库中比远程更新,那么会执行类似git reset --hard的指令强制更新为远程的。所以执行这个命令的时候要小心。因为它会洗掉本地与远端不同的内容「1」。在bare tree也没有什么类似git pull的功能。


-------以下是初始化本地项目文件夹,并添加到远程的库------

初始化版本库,并提交到远程服务器端 mkdir WebApp cd WebApp 

git init本地初始化 

touch README
git add README添加文件 git commit -m 'first commit'
git remote add origin [email protected]:daixu/WebApp.git 增加一个远程服务器端  
上面的命令会增加URL地址为'[email protected]:daixu/WebApp.git',名称为origin的远程服务器库,以后提交代码的时候只需要使用 origin别名即可           
 后面就可以用 git add .

git commit -m'add file'

git push origin master

来提交改动的文件到库了

--- Git 常用命令速查 ---

    
git branch 查看本地所有分支

git status 查看当前状态 

git commit 提交  
git branch -a 查看所有的分支

git branch -r 查看远程所有分支

git commit -am "init" 提交并且加注释  
git remote add origin [email protected]:ndshow


git push origin master 将文件给推到服务器上 

git remote show origin 显示远程库origin里的资源 

git push origin master:develop 
git push origin master:hb-dev

将本地库与服务器上的库进行关联 


git checkout --track origin/dev 切换到远程dev分支

git branch -D master develop 删除本地库develop

git checkout -b dev 建立一个新的本地分支dev

git merge origin/dev 将分支dev与当前分支进行合并

git checkout dev 切换到本地dev分支

git remote show 查看远程库 git add . 
git rm 文件名(包括路径) 从git中删除指定文件 


git clone git://github.com/schacon/grit.git 从服务器上将代码给拉下来

git config --list 看所有用户

git ls-files 看已经被提交的

git rm [file name] 删除一个文件 
git commit -a 提交当前repos的所有的改变

git add [file name] 添加一个文件到git index 

$ git add -f XXX/.nuget/NuGet.exe    #强制提交一个文件,因为有可能是ingor忽略文件禁止提交的

git commit -v 当你用-v参数的时候可以看commit的差异 
git commit -m "This is the message describing the commit" 添加commit信息

git commit -a -a是代表add,把所有的change加到git index里然后再commit

git commit -a -v 一般提交命令

git log 看你commit的日志

git diff 查看尚未暂存的更新 
git rm a.a 移除文件(从暂存区和工作区中删除)

git rm --cached a.a 移除文件(只从暂存区中删除)

git commit -m "remove" 移除文件(从Git中删除)

git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)

git diff --cached 或 $

git diff --staged 查看尚未提交的更新

git stash push 将文件给push到一个临时空间中

git stash pop 将文件从临时空间pop下来 

git remote add origin [email protected]:username/Hello-World.git

git push origin master 将本地项目给提交到服务器
 

git pull 本地与服务器端同步 

git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。

git push origin serverfix:awesomebranch 
git fetch 相当于是从远程获取最新版本到本地,不会自动merge 
git commit -a -m "log_message" (-a是提交所有改动,-m是加入log信息) 本地修改同步至服务器端 :

git branch branch_0.1 master 从主分支master创建branch_0.1分支

git branch -m branch_0.1 branch_1.0 将branch_0.1重命名为branch_1.0 git checkout branch_1.0/master 切换到branch_1.0/master分支 du -hs      
git branch 删除远程branch   
git push origin :branch_remote_name   
git branch -r -d branch_remote_name  

git clone url 复制代码库
git add filename  添加文件到暂存
git add . 添加所有的文件
git add -A  添加所有文件包括已经删除的问题到暂存
git ci -m'注释 '  形成一个commit
git df 未暂存的代码与原库的差别
git dfs 暂存中的代码与原库的差别
git reset filename 将代码从暂存状态释放
git reset . 释放所有的暂存代码
git co filname 重置文件
git co .重置所有的问题件
git push 将代码推送到服务器上面的代码库
git pull 从服务器拉取代码

git status 查看当前状态
git rm filename 从暂存和工作区删除文件
git rm --cached filename 未验证


//获取远程分支代码
git fetch
git co -b newbranch  origin/branch

建立本地dev与远程dev的链接

$ cd c:/HQ.Job/hq.gittest

git branch --set-upstream dev origin/dev
or 
git branch --track dev origin/dev #建立本地dev与远程dev的链接

git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态
git stash #把所有没有提交的修改暂存到stash里面。可用git stash pop回复。
git reset --hard HASH #返回到某个节点,不保留修改。
git reset --soft HASH #返回到某个节点。保留修改
git fetch --all 放弃本地修改,强制更新

--- 不同分支的合并同步 ---

该操作适合开发阶段不同时间点的不同版本的更新
比如dev是开发的用的分支 1.9是内部测试的版本,现在要把最新的dev版本同步到1.9的测试版本,操作如下
dev to 1.9

#先切换到dev分支
git checkout dev
#更新最新的dev到本地
git pull

#切换到1.9分支
git checkout 1.9
#把dev分支合并到1.9
git merge dev
#将1.9更新到版本库(远程)1.9分支
git push origin 1.9

-1.9 to 1.100-

git checkout 1.100
git merge 1.9
git push origin 1.100

--- 如何用git reflog和git cherry-pick找回已删除的commit记录 ---


commit2: add test2.c
commit1: add test1.c
模拟丢失commit记录的情况,执行git reset --hard HEAD~1,删除了commit3,同时test3.c文件已经在working tree里看不到了,如果要恢复commit3,就要使用git reflog和git cherry-pick.
$ git reflog
502dd0f HEAD@{0}: HEAD~1: updating HEAD
147b3b5 HEAD@{1}: commit: test3
502dd0f HEAD@{2}: commit: test2
0692c03 HEAD@{3}: commit (initial): test1
HEAD@{0}: HEAD~1: updating HEAD
红色加粗的即是被删除了的 commit3,运行git log则没有这一行记录,可以使用git reset --hard 502dd0f
将红色记录删除,恢复cmmit3,需要用git cherry-pick.
$ git cherry-pick 147b3b5
[master 02c1e69] test3
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test3.c


git 的错误操作,导致丢失了重要的commit,真是痛不欲生; 
最后通过git神器终于找回了丢失的commit,但是需要总结和反思的地方有一些,同时需要加深git的学习,特献上本文以供参考 


执行git reset --hard HEAD~1 ,删除了commit3,但是发现reset错了,晕菜了…… 
还好有后悔药(感叹git的强大啊,神马意外情况都考虑到了)满血恢复commit3,执行如下步骤: 
Java代码  收藏代码
git reflog  
502dd0f HEAD@{0}: HEAD~1: updating HEAD  
147b3b5 HEAD@{1}: commit: test3  
502dd0f HEAD@{2}: commit: test2  
0692c03 HEAD@{3}: commit (initial): test1  
  
git reset --hard 502dd0f  
git cherry-pick 147b3b5  


丢失的commit3终于回来啦~~~~ 
虽然有利器,但是需要总结和反思的是,慎用reset hard啊,实在不行reset merge也是不错的选择。 

=================================================== 

通过这次错误的使用reset,反思需要加强对reset的了解,不能再盲目的使用了 

git reset [--hard|soft|mixed|merge|keep] [或HEAD] 
作用:将当前分支reset到指定的或者HEAD(默认为最新的一次提交,即重设到最新一次提交之前的版本) 

备注: 
       index,执行git add的操作,会对文件创建索引,所有被跟踪的文件索引会放入index,表示文件被修改待提交
       working tree,当前工作区,被修改但未被add的文件,存储在工作区 
       ORIG_HEAD,用于指向前一个操作状态,每次的commit或者pull或者reset,git 都会把老的HEAD拷贝到.git/ORIG_HEAD,通过对ORIG_HEAD的引用可    以指向前一次的操作状态 

1、hard(慎用) 
重设index和working tree,所有改变都会被丢弃,包括文件的修改、新增、删除等操作,并把HEAD指向, 
因此通过git log查看版本提交记录,被reset的版本记录会被丢弃,但可以通过git reflog查看 

2、soft 
不重设index和working tree,仅仅将HEAD指向,表示已经commit的文件会取消commit, 
通过git status查看,文件会处于待commit状态“Changes to be committed” 

3、mixed(默认) 
重设index,但不重设working tree,表示已经被add的文件,被取消add, 
通过git status查看,文件会处于待添加索引状态 “Changes not staged for commit” 

4、merge 
重设index,重设working tree中发生变化的文件,但是保留index和working tree不一致的文件 

5、keep 
重设index,重设working tree中发生变化的文件


查看某个文件的修改记录

git whatchanged App.config

先进到App.config的当前目录 再运行上面的命令,即可看到该文件的所有修改历史,查看某个commit的修改内容用下面的命令

git show 哈希码

每个commit都有一个哈希码

---杂项问题---

有时 git log ,git diff 是光标处出现 (end)按回车也没用,要按 "q"即可


在用git ls -5 ,git log 时提示terminal is not fully functional


在命令行执行 export TERM=msys 即可


附:如果是windows 系统 在命令行执行 TERM=msys 即可


将新的本地项目添加到github


1 首先在https://github.com登录后创建一个new repository,我建的是public类型的,https访问方式
  这样得到一个库地址,如  https://github.com/这里是你的账号/这里是库名称.git 
2 本地需要先安装客户端,我装的是git bash
3 在你的项目文件夹下,右键-git bash here 打开命令窗口 依次执行下面的命令
0 touch .gitignore 在文件夹就生成了一个“.gitignore”文件,然后用编辑器打开该文件,把不需要上传的文件列在这里,如下 补充的.gitigno部分,这步也可以省略,这样所有的文件都将上传 
1、git init //初始化项目,执行完此命令后会生成一个.git文件夹 
2、git add . 或 git add --all //将本地项目所有文件添加到git管理,.指全部文件 
3、git commit -m “提交描述" 
4、git remote add origin 刚刚新建的Github地址 
5、git push -u origin master
这样本地的项目就提交到git库了,用git clone 库地址就要以下载

下面的两个命令是用来配置用户信息的
git config --global user.name  sanxian 
git config --global user.email [email protected]

git add README.md 是添加一个类似修改log或注意事项的文件,会在项目页中显示

后续有修改一般下面的操作就够了
git status //查看有哪些修改
git add --all
git commit -m'修改说明'
git push //会要求输入账号,密码
就ok了

---.gitignore 创建和使用 ---

1. 在需要创建  .gitignore 文件的文件夹, 右键选择

Git Bash 进入命令行,进入项目所在目录。

2. 输入 touch .gitignore 在文件夹就生成了一个“.gitignore”文件。

然后在”.gitignore” 文件里输入你要忽略的文件夹及其文件就可以了。

# compiled files
obj
bin
# user files
.user
.suo

Git 的 .gitignore 配置
.gitignore 配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为我们的版本管理带来很大的便利,以下是个人对于配置 .gitignore 的一些心得。


1、配置语法:

  以斜杠“/”开头表示目录;

  以星号“*”通配多个字符;

  以问号“?”通配单个字符

  以方括号“[]”包含单个字符的匹配列表;

  以叹号“!”表示不忽略(跟踪)匹配到的文件或目录;

  此外,git 对于 .ignore 配置文件是按行从上到下进行规则匹配的,意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效;

2、示例:

  (1)规则:fd1/*
      说明:忽略目录 fd1 下的全部内容;注意,不管是根目录下的 /fd1/ 目录,还是某个子目录 /child/fd1/ 目录,都会被忽略;

  (2)规则:/fd1/*
      说明:忽略根目录下的 /fd1/ 目录的全部内容;

  (3)规则:

/*
!.gitignore
!/fw/bin/
!/fw/sf/

说明:忽略全部内容,但是不忽略 .gitignore 文件、根目录下的 /fw/bin/ 和 /fw/sf/ 目录;


--- end ---


下面是一个比较完整的git使用介绍的文章

http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/00137583770360579bc4b458f044ce7afed3df579123eca000



你可能感兴趣的:(Tools,转载)