git 日常操作笔记

[Modify][SettingsProvider]默认XXX

[Delete]

[Update]  对上一次提交的补充

[Fix] 上一次提交造成的编译不成功


搭建Git服务器-SCM-Manager

基于配置简单的原则,先试用一下SCM-Manager Home | SCM-Manager 


git 学习推荐文章:

今年下半年,中日合拍的《Git游记》即将正式开机,我将…(上集)_Coder-Pig的猪栏-CSDN博客

一个小时学会Git - 张果 - 博客园


基本概念

我们先来理解下Git 工作区、暂存区和版本库概念

  • 工作区:就是你在电脑里能看到的目录。
  • 暂存区:英文叫stage, 或index。一般存放在 ".git目录下" 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
  • 版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

下面这个图展示了工作区、版本库中的暂存区和版本库之间的关系:

 

     Git的四个组成部分

简单说下Git的四个组成部分:

工作区:不包含.git文件夹在内的整个项目目录,所有修改都在工作区内进行。
暂存区:又称索引区,本地文件修改后,执行add操作会把工作区的修改添加到缓存区。
本地仓库:当执行commit操作时,暂存区的数据被记录到本地仓库中。
远程仓库:托管项目代码的服务器,多人协作时通过远程仓库进行代码同合并与同步。

接下来说下这几个部分是如何协同工作的:

A:  工作区与暂存区:工作区更改,通过git add命令可以把更改提交到暂存区;
也可以git checkout命令使用暂存区内容覆盖当前的工作区的内容。
 
B:  暂存区与本地仓库:可以通过git commit命令把暂存区的内容提交到本地仓库,
每次commit都会生成一个快照,快照使用Hash值编号。可以通过git reset Hash值,
把某个快照还原到暂存区中。
 
C:  工作区和本地仓库:通过git checkout 快照编号,直接把某个快照还原到工作区中。
 
D:  本地仓库和远程仓库:可以通过git push命令把commit推送到远程仓库,多人协作的
时候可能还需要进行一些冲突处理;还有通过git clone拉取某个远程仓库的项目到本地,
或通过git fetch拉取远程仓库的最新内容,检查后决定是否合并到本地仓库中。
 
E:  工作区和远程仓库:这里两者的协作一般是git pull,即把远程主机的最新内容拉取下来后直接合并。

     Git中文件的几个状态

按照大类划分,可以分为两种状态:Tracked(已跟踪)和Untracked(未跟踪),
依据是:「该文件是否已加入版本控制」?

文件状态变化周期流程图

流程简述

假设某个项目已加入Git版本控制系统

1.新建一个文件,该文件处于 Untracked 状态;
2.通过git add命令添加到缓存区,此时文件处于**Tracked状态又或者说
此时这个文件已经被版本控制系统所跟踪,而且他处于Staged**(暂存)状态;
3.通过git commit命令把暂存区的文件提交提交到本地仓库,此时文件处于
Unmodified(未修改)状态;
4.此时如果去编辑这个文件,文件又会变成**Modified**(修改)状态;


工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。

git-repo

我们把文件往Git版本库里添加的时候,是分两步执行的:

第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;

第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改


git 的具体安装看此文章:

Ubuntu下git的安装与使用 - L.X.M - 博客园

方法一:配置个人的用户名称和电子邮件地址: 如果你是用的别人的电脑,别人以经配置过用户与邮箱了,你也可以用此命令修改config配置

$ git config --global user.name "xxxx"
$ git config --global user.email test@163.com

git config --global pull.rebase true      //此命令默然将为  git pull  转换git pull --rebase  执行,即执行:git pull  等效于执行 git pull --rebase

方法二:直接修改git的配置文件的方式来进行修改

       1) 打开全局的.gitconfig文件的命令为:$  vi ~/.gitconfig;   然后在文件中直接修改即可

如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。

如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。

git  文本编辑器  

一般git默然的编辑器是: nano,

设置Git默认使用的文本编辑器, 一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置::

$ git config --global core.editor vim          //设置vim为git 默认编辑器

差异分析工具

还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:

$ git config --global merge.tool vimdiff

要检查已有的配置信息,可以使用 git config --list 命令:

git config -e --global 查看配置文件的位置。


获取git仓库的两个方式。

【1】通过git clone方式,即如字意 clone服务器上项目的地址 ,然后将远程服务器中的项目clone到本地

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

git clone -b 分支名称 代码仓库地址

git clone -b dev git://github.com/schacon/grit.git   //git clone 指定位取仓库dev分支

git submodule update --init --recursive    // clone中断 ,可用此命令继续下载

git clone 命令可以从原本已经存在的远端仓库中,下载和创建为本地仓库。
进入一个新建目录下,执行以下命令
$ git clone <git_url>
这个命令会将远端仓库的代码以及 git 记录下载到本地,创建为本地仓库

【2】本地初始化一个Git仓库,使用git init命令。

自己可以在本地创建任意一个目录进入目录中执行

git init 命令即可将此目录设置你的本地的库,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。执行此命令后在此目录下会自动生成一个.get文件,其中就

添加文件到Git仓库,分两步:

  1. 使用命令git add <file>,注意,可反复多次使用,添加多个文件;
  2. 使用命令git commit -m <message>,完成

git push 命令讲解

要关联一个远程库,使用命令

git remote add origin git@server-name:path/repo-name.git

关联后,使用命令此命令,代码第一次推送master分支的所有内容;

git push -u origin master

此后,每次本地提交后,只要有必要,就可以使用命令推送最新修改;

git push origin master

git push命令用于将本地分支的更新,推送到远程主机。它的格式与git pull命令相仿

git push <远程主机名> <本地分支名>:<远程分支名>

如果省略远程分支名,则表示将本地分支推送与之存在”追踪关系”的远程分支(通常两者同名),如果该远程分支不存在,则会被新建。

1

$ git push origin master

上面命令表示,将本地的master分支推送到origin主机的master分支。如果后者不存在,则会被新建。

如果省略本地分支名,则表示删除指定的远程分支,因为这等同于推送一个空的本地分支到远程分支。

1

2

3

$ git push origin :master

# 等同于

$ git push origin --delete master

远程库: 远程分支名  它们中间有:是删除,有符号: 与没法有符号是两个不结果的操作命令

推送你的新分支与数据到某个远端仓库命令:

git push [alias] [branch]

以上命令将你的 [branch] 分支推送成为 [alias] 远程仓库上的 [branch] 分支,实例如下。

上面命令表示删除origin主机的master分支。

如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。

1

$ git push origin

上面命令表示,将当前分支推送到origin主机的对应分支。

如果当前分支只有一个追踪分支,那么主机名都可以省略。

1

$ git push


(1) 命令创建一个远程库,(2)本地分支与创建的远程库的master  分支关联,
git remote add origin https://github.com/xxxxx/repositoryname.git
git push -u origin master

如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,这样以后就可以不加任何参数使用git push。

1

$ git push -u origin master

上面命令将本地的master分支推送到origin主机,同时指定origin为默认主机,后面就可以不加任何参数使用git push了。

不带任何参数的git push,默认只推送当前分支,

还有一种情况,就是不管是否存在对应的远程分支,将本地的所有分支都推送到远程主机,这时需要使用–all选项。

1

$ git push --all origin

上面命令表示,将所有本地分支都推送到origin主机。

如果远程主机的版本比本地版本更新,推送时Git会报错,要求先在本地做git pull合并差异,然后再推送到远程主机。这时,如果你一定要推送,可以使用–force选项。

1

$ git push --force origin

上面命令使用–force选项,结果导致在远程主机产生一个”非直进式”的合并(non-fast-forward merge)。除非你很确定要这样做,否则应该尽量避免使用–force选项。

最后,git push不会推送标签(tag),除非使用–tags选项。

1

$ git push origin --tags

其它示例

1.推送本地分支lbranch-1到新大远程分支rbranch-1

$ git push origin lbranch-1:refs/rbranch-1

2.推送lbranch-2到已有的rbranch-1,用于补充rbranch-1

$ git checkout lbranch-2
$ git rebase rbranch-1
$ git push origin lbranch-2:refs/rbranch-1

3.用本地分支lbranch-3覆盖远程分支rbranch-1

$ git push -f origin lbranch-2:refs/rbranch-1

7.使用push命令,将代码提交到远程对应分支
    git push <远程主机名> <本地分支名>:<远程分支名>

    git push test master:jenkinsapi

#test 为设置的远程仓库别名,master为本地分支名,jenkinsapi为远程分支名

使用git push origin issue5560:master 就可以把本地分支issue5560推送到远程origin库的master分支了。
  

如果想把本地的某个分支test提交到远程仓库,并作为远程仓库的master分支,或者作为另外一个名叫test的分支,那么可以这么做。

$ git push origin test:master         // 提交本地test分支作为远程的master分支
$ git push origin test:test              // 提交本地test分支作为远程的test分支

git pull讲解

命令用于从另一个存储库或本地分支获取并集成(整合)。

git pull命令的作用是:取回远程主机某个分支的更新,再与本地的指定分支合并

格式:git pull  <远程主机名> <远程分支名>:<本地分支名>

对比 git push <远程主机名> <本地分支名>:<远程分支名>

     这里注意,很多时间就是没有注意搞得头晕

1. 如果与当前分支合并,则可省略本地分支名

git pull <远程主机名> <远程分支名> 

相当于:git fetch <远程主机名> <远程分支名>

           git merge <远程主机名>/<远程分支名>

2. 如果当前分支与远程分支存在追踪关系

git pull <远程主机名>

3. 如果当前分支只有一个追踪关系

git pull

4. 手动建立追踪关系

git branch --set-upstream master origin/next

5. 清理远程已删除本地还存在的分支

git fetch --prune origin

或者 git fetch -p

或者 git pull -p

以下是一些示例 -

$ git pull <远程主机名> <远程分支名>:<本地分支名>

比如,要取回origin主机的next分支,与本地的master分支合并,需要写成下面这样 -

$ git pull origin next:master

如果远程分支(next)要与当前分支合并,则冒号后面的部分可以省略。上面命令可以简写为:

$ git pull origin next

上面命令表示,取回origin/next分支,再与当前分支合并。实质上,这等同于先做git fetch,再执行git merge

$ git fetch origin
$ git merge origin/next

将两个已创建且完全不搭边的库关联到一起

在某些场合,Git会自动在本地分支与远程分支之间,建立一种追踪关系(tracking)。比如,在git clone的时候,所有本地分支默认与远程主机的同名分支,建立追踪关系,也就是说,本地的master分支自动”追踪”origin/master分支。但如果本地库与远程库是两个都还未关联的项目时,就得大家手自建立关系,

Git也允许手动建立追踪关系。

$ git branch --set-upstream master origin/next

上面命令指定master分支追踪origin/next分支。

或者是:

Github新建一个仓库,写了License,然后把本地一个写了很久仓库上传。 先pull,因为两个仓库不同,

发现refusing to merge unrelated histories,无法pull 因为他们是两个不同的项目,要把两个不同的项目合并,

git需要添加一句代码,在git pull, 这句代码是在git 2.9.2版本发生的,最新的版本需要添加--allow-unrelated-histories

git pull origin master --allow-unrelated-histories


如果当前分支与远程分支存在追踪关系,git pull就可以省略远程分支名。

$ git pull origin

上面命令表示,本地的当前分支自动与对应的origin主机”追踪分支”(remote-tracking branch)进行合并。

如果当前分支只有一个追踪分支,连远程主机名都可以省略。

$ git pull  更新代码的时候尽量使用 git pull --rebase

上面命令表示,当前分支自动与唯一一个追踪分支进行合并。

如果合并需要采用rebase模式,可以使用–rebase选项。

$ git pull --rebase <远程主机名> <远程分支名>:<本地分支名>

使用下面的关系区别这两个操作:
git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase


如果你的工作区有修改的文件都但你没有commit,就执行git pull --rebase git 执行git pull –rebase报错误如下: 

error: Cannot pull with rebase: You have unstaged changes. 
error: Additionally, your index contains uncommitted changes. 

原因:如果有未提交的更改,是不能git pull的

è¿éåå¾çæè¿°

解决: 
先执行git stash 
再执行git pull –rebase 
最后再执行git stash pop   或是  git stash apply    作用一样

解释--
a.把你 commit 到本地仓库的内容,取出来放到暂存区(stash)(这时你的工作区是干净的) 
b.然后从远端拉取代码到本地,由于工作区是干净的,所以不会有冲突 
c.从暂存区把你之前提交的内容取出来,跟拉下来的代码合并


git fetch和git pull的区别

  1. git fetch:相当于是从远程获取最新版本到本地,不会自动合并。

$ git fetch origin master
$ git log -p master..origin/master
$ git merge origin/master
以上命令的含义:

  • 首先从远程的originmaster主分支下载最新的版本到origin/master分支上
  • 然后比较本地的master分支和origin/master分支的差别
  • 最后进行合并

上述过程其实可以用以下更清晰的方式来进行:

$ git fetch origin master:tmp
$ git diff tmp 
$ git merge tmp
2. git pull:相当于是从远程获取最新版本并merge到本地

git pull origin master

上述命令其实相当于git fetchgit merge
在实际使用中,git fetch更安全一些,因为在merge前,我们可以查看更新情况,然后再决定是否合并。
git pull --rebase,

我们在使用git pull命令的时候,可以使用--rebase参数,即git pull --rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上

两者的区别可以用下面的关系式来表示:
git pull = git fetch + git merge
git pull --rebase = git fetch + git rebase

个人建议:在大部分时候合并代码或是更新代码时,推荐使用git rebase  --branchname, git pull --rebase;不推荐git merge


git branch 查看本地所有分支

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

git log --decorat  功能差不多的其它命i令(git  branch -av)

如果当前本地分支命令非常不规范,分不清本地分支是对应哪个过程分支时,可用此命令查看,当前所处的本地分支对应哪个远程分支,

同样git branch -vv 命令也可以查看当前本地分支与远程分支的关联对应关系

git branch -vv 查看本地分支与远程分支追踪状态

git commit -am "init" 提交并且加注释 
git remote add origin git@192.168.1.119:ndshow
git push origin master 将文件给推到服务器上 
git remote show origin 显示远程库origin里的资源 
git push origin master:develop 将本地master分支推送到远程origin库中的devolop分支
git push origin master:hb-dev 将本地库与服务器上的库进行关联 
git checkout --track origin/dev 切换到远程dev分支
git branch -D master develop 强制删除本地库develop

git branch -d master develop 删除本地库develop
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将远程分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支

git remote rm [远程库名]      删除远程仓库
git remote show    查看远程库


git add .
git rm 文件名(包括路径) 从git中删除指定文件

git config --list 看所有用户
git ls-files 看已经被提交的

git rm a.a 移除文件(从暂存区和工作区中删除)
git rm --cached a.a 移除文件(只从暂存区中删除)
git rm -f a.a 强行移除修改后文件(从暂存区和工作区中删除)
git rm [file name] 是从暂存区域删除文件,这样以后就不会出现在未跟踪文件清单中了。

如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changes not staged for commit” 部分(也就是未暂存清单) 看到你git rm 删除的文件操作记录, 然后再运行 git rm 记录此次移除文件的操作,最后提交的时候,该文件就不再纳入版本管理了

另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。换句话说,仅是从跟踪清单中删除。比如一些大型日志文件或者一堆 .a 编译文件,不小心纳入仓库后,要移除跟踪但不删除文件,以便稍后在 .gitignore 文件中补上,用 --cached 选项即可

git rm --cached readme.txt

git commit --amend 修改上一次的提交信息。//git commit --amend -m "新备注信息"
git commit -a 提交当前repos的所有的改变
git add [file name] 添加一个文件到git index
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 diff:是查看 workspace(工作区) 与 index(暂存区) 的差别的。
git diff --cached:是查看 index(暂存区) 与 local repositorty(本地仓库) 的差别的。
git diff HEAD:是查看 workspace 和 local repository 的差别的。(HEAD 指向的是 local repository 中最新提交的版本)

git diff 显示工作目录与索引文件之间的差异

git diff –cached显示索引文件与git仓库之间的差异

git diff HEAD 显示工作目录与git仓库之间的差异,

git diff HEAD 显示工作目录与git仓库之间的差异,而git diff HEAD^ 则显示上一次提交之前工作目录与git仓库之间的差异。所以我们在git pull后,

可以通过 git diff HEAD^  来查看拉下来的文件有那些具体的修改。(此命令与 git diff -p -1 命令作用和结果一样,都是查看最新一个更新的具体修改内容 

git diff 查看尚未暂存的修改,比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。

git diff --cached 或 $ git diff --staged 查看尚未提交的更新,但已存入暂存区的修改,要查看已经暂存起来的文件和上次提交时的快照之间的差异,

git diff --cached 查看所有已经存入暂存区的修改

git diff --cached  filename  单独查看 已存入暂存区filename的修改 

git diff HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别:

查看尚未暂存的文件更新了哪些部分 git diff filename                      

查看已经暂存起来的文件和上次提交的版本之间的差异 git diff –cached filename           

查看已经暂存起来的某个文件和上次提交的版本之间的差异 git diff ffd98xxx b8e7xxxxx 

查看某两个版本之间的差异 git diff ffd9xxxx:filename b8e7xxx:filename 查看某两个版本的某个文件之间的差异



git stash push 将文件给push到一个临时空间中
git stash pop 将文件从临时空间pop下来
---------------------------------------------------------
git remote add origin git@github.com:username/Hello-World.git
git push origin master 将本地项目给提交到服务器中
-----------------------------------------------------------
git pull 本地与服务器端同步
-----------------------------------------------------------------
git push (远程仓库名) (分支名) 将本地分支推送到服务器上去。
git push origin serverfix:awesomebranch
------------------------------------------------------------------
git fetch 相当于是从远程获取最新版本到本地,不会自动merge
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 branch -m <oldname> <newname>

如果要重命名当前分支,可以执行以下操作:
git branch -m <newname>

一种记住方式是-m表示“移动”(或mv ),这是您重命名文件的方式。
如果您使用的是Windows或其他不区分大小写的文件系统,并且名称中有大小写更改,则需要使用-M ,否则git会抛出分支已经存在的错误:
git branch -M <newname>

git checkout branch_1.0/master 切换到branch_1.0/master分支


git clean命令用来从你的工作目录中删除所有没有tracked过的文件

git clean -n 是一次clean的演习, 告诉你哪些文件会被删除. 记住他不会真正的删除文件, 只是一个提醒

git clean -f 删除当前目录下所有没有track过的文件. 他不会删除.gitignore文件里面指定的文件夹和文件, 不管这些文件有没有被track过

git clean -f <path> 删除指定路径下的没有被track过的文件

git clean -df 删除当前目录下没有被track过的文件和文件夹 git clean -xf 删除当前目录下所有没有track过的文件. 不管他是否是.gitignore文件里面指定的文件夹和文件

git clean -fdx 清除此类未被跟踪的文件

git reset --hard和git clean -f是一对好基友. 结合使用他们能让你的工作目录完全回退到最近一次commit的时候,

git clean -xdf && git reset --hard && git pull  (与服务器最新代码保持一致)


git log 看你commit的日志

git log -- file   查看某一个文件的修改记录,如SystemUI.java:    git log -- SystemUI.java 

git log -p filename  可以显示该文件每次提交的diff

git log -p -2 用 -2 则仅显示最近的两次更新

git log --graph命令可以看到分支合并图

git log --stat   --stat,仅显示简要的增改行数统计(如 git log -3 --stat  显示最近三次修改的文件)

git log --pretty=oneline    oneline 将每个提交放在一行显示,这在提交数很大时非常有用。另外还有 shortfull 和 fuller 

git log --decorat  功能差不多的其它命i令(git  branch -av)

git log --author=xxxx  过滤某人的提交记录,

 git log -n 1 -p  看最近一次提交所有更改的细节

你也可以用正则表达式来创建更复杂的检索。比如,下面这个命令检索名叫Mary或John的作者的提交。

git log --author="John\|Mary"

git log --oneline | grep "QQ"    通过commit提交信息查找

git blame  查看某个文件的改动详细记录(所有人每次修改记录)


查看本地分支【领先】远程分支的commit具体修改内容

 如上图, 查看分支后,提示本地分支领先于远程分支3个提交,但在我印象中此分支已有好快一个月未在此分支上修改了,怎么会提示我领先于远程分支3个提交了,通过git log也查不到 因为这段时间内其它人提交了很多的commit,但我又想看看这三个commit 具体修改了些什么内容,不敢盲目push到远程分支造成其它问题,后面才想到可以用 :

git log --author=xxxx  过滤自己的名字查看,最近三个commit,这3个commit就是merge的记录,可以直接push 


git commit --amend的使用情景是当前修改并未提交至远程库中(未执行git push  之前的漏文件补救)

git commit -a -m "log_message" (-a是提交所有改动,-m是加入log信息) 本地修改同步至服务器端 :

git commit --amend  有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用

如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

git reset HEAD <file>... 撤销从工作目录中提交gita add到暂存区域的  如不小心用 git add . 全加到了暂存区域。该如何撤消暂存其中的一个文件呢,//  git rm --cached -r .   此命令效果一样

git checkout file取消到工作目录中文件的修改

git checkout -f HEAD   (此命令与git reset --hard HEAD  类似)  下载最新的版本文件到本地

git reset --hard   下载最新的版本文件到本地, 不是回退到上已版本 与git reset --hard HEAD^  有区别

 git reset --hard HEAD^  回退到上一个版本,用HEAD表示当前版本,也就是最新的提交1094adb...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

git reset --hard 1094a  后面的HASH码  可以通过执行git log查看,一般写前面四位即可,当然你也可以完整的

先在本地回退到相应的版本:    git commit之后,想撤销commit

git reset --hard <版本号>
// 注意使用 --hard 参数会抛弃当前工作区的修改(当前工作目录下 modify状态的文件都会被reset 清除修改,只是保留commit中修改 )
// 使用 --soft 参数的话会回退到之前的版本,但是保留当前工作区的修改,可以重新提交


【本地代码库回滚】---即:撤销git commit的内容

git reset --soft HEAD^

HEAD^的意思是上一个版本,也可以写成HEAD~1

如果你进行了2次commit,想都撤回,可以使用HEAD~2

至于这几个参数:
--mixed 

意思是:不删除工作空间改动代码,撤销commit,并且撤销git add . 操作

这个为默认参数,git reset --mixed HEAD^ 和 git reset HEAD^ 效果是一样的。
--soft  

不删除工作空间改动代码,撤销commit,不撤销git add . 
--hard

删除工作空间改动代码,撤销commit,撤销git add . 

注意完成这个操作后,就恢复到了上一次的commit状态。

git reset --hard commit-id :回滚到commit-id,讲commit-id之后提交的commit都去除

git reset --hard HEAD~3:将最近3次的提交回滚


(1)方法【远程代码库回滚】--先后执行以下两条命令:

第一步: git reset --soft HEAD^ | git reset --soft <版本号>      先回滚本地的代码

第二步:git add 添加你漏提交的文件,  【或是原有提交的文件再修改后的文件(此时可不需要将原有提交文件git reset HEAD filename,再修改,再git add filename,可又直接修改原有文件,再git add ,没必须执行git reset HEAD 操作 )】

第三步:git commit  添加修改备注信息

第四步: git push origin master --force 会提示本地的版本落后于远端的版本 所以得加参数--force   强制提交  //master为当前本地所在的分支名

hjk@hjk-optiplex:~/workcode/xxxx$ git push    //这里一定要用 git push origin master --force 命令强制推送,否则会推送不上去了,会报以下错误,
To xxxxxxx:../../var/aaa/xxxx/bbb
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@123456789:../../var/aaa/xxxx/bbb'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

如果你只是想回滚push操作,取消push,则是:

第一步: git reset --soft HEAD^   | git reset --soft <版本号>      先回滚本地的代码

第二步: git push origin master --force 直接提交覆盖,不需要再执行其它

--------------------------------------------------------------------------------------------------------------------------------------------------------------

(2) 方法 git撤销已经push到远端的commit  (具体实例示范: git撤回push到远程的代码 - Se7end - 博客园   操作验证过OK)

在使用git时,push到远端后发现commit了多余的文件,或者希望能够回退到以前的版本。

先在本地回退到相应的版本:

git reset --hard <版本号>
// 注意使用 --hard 参数会抛弃当前工作区的修改
// 使用 --soft 参数的话会回退到之前的版本且会保留当前工作区的修改,可以重新提交
如果此时使用命令:

git push origin <分支名>

执行上面命令后会提示本地的版本落后于远端的版本,

为了覆盖掉远端的版本信息,使远端的仓库也回退到相应的版本,需要加上参数--force

git push origin <分支名> --force   //如果当前分支已与远程分支关联了,可以直接 adb push --force
 


git revert   是生成一个新的提交来撤销某次提交,此次提交之前的commit都会被保留

git reset    是回到某次提交,提交及之前的commit都会被保留,但是此次之后的修改都会被退回到暂存区


 git reflog   如果你用git reset -- hard HEAD 到了某个版本 但最后又觉得之前某一新版本才是最理想的版本,想恢复到新版本怎么办?而且找不到新版本的commit id怎么办?Git提供了一个命令 git reflog 用来记录你的每一次命令,要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。


2 若查看某一次提交的内容,执行下面命令(可以不加--stat)

git show commit  --stat( 只会列出文件名)

3、git show comit_id  filename
可以查看某次提交中的某个文件变化

4、git show commit_id
查看某次提交

5、gitk --follow filename
以图形化界面的方式显示修改列表

git apply  应用补丁


远程 分支问题:

跟踪远程分支
1)如果远程新建了一个分支,本地没有该分支,可以用git checkout --track origin/branch_name,这时候本地会新建一个分支名叫branch_name,会自动跟踪远程的同名分支branch_name。


2)用上面中方法,得到的分支名永远和远程的分支名一样,如果想新建一个本地分支不同名字,同时跟踪一个远程分支可以利用。
git checkout -b new_branch_name branch_name,这条指令本来是根据一个branch_name分支分出一个本地分支new_branch_name,但是如果所根据的分支branch_name是一个远程分支名,那么本地的分支会自动的track远程分支。建议跟踪分支和被跟踪远程分支同名。

总结:一般我们就用

git push --set-upstream origin branch_name  来在远程创建一个与本地branch_name同名的分支并跟踪;

git checkout --track origin/branch_name  来在本地创建一个与branch_name同名分支跟踪远程分支


Git merge 不同的branch

Git的优势是可以创建不同的branch,然后在每个branch上开发。那么问题是:如果不同的branch之间需要做同步,比如sourceBranch上做的修改也需要同步到targetBranch,改怎么做?

A). 如果一个branchA (targetBranch)是有远程Git server管理的,另一个branchB (sourceBranch)是自己本地的,即把sourceBranch的修改merge到targetBranch上:

   1. cd <your workspace>

   2. git branch  //假定现在所在的branch是targetBranch,并最好保证没有未提交的修改,并且已经更新到最新

   3. git checkout -b branchB  //创建一个本地的sourceBranch并切换到sourceBranch

   4. git commit  //把sourceBranch上做的修改先提交

   5. git checkout branchA  //切换回targetBranch

   6. git merge --no-ff branchB  //把sourceBranch的修改merge到targetBranch。注意:建议merge的时候总是用 --no-ff 选项

   7git status  //保证现在workspace是干净的

   8. git push origin branchA //push到远程,如果远程有新的修改,先做一下git pull

B). 如果两个branch都是远程管理的,想把branchB (sourceBranch)的内容同步到branchA (targetBranch)上

   1. cd <your workspace>

   2. git branch  //假定现在所在的branch是branchA (targetBranch),并最好保证没有未提交的修改,并且已经更新到最新

   3. git checkout branchB  //确保同一个workspace能在不同的branch直接切换,即保证 .git/config里 [remote "origin"] 的内容是 fetch = +refs/heads/*:refs/remotes/origin/*

   4. git merge branchA //先把targetBranch的修改merge到sourceBranch上,这样有冲突可以在sourceBranch上先解决,保证之后再merge回targetBranch的时候容易处理,targetBranch不再有冲突

   5. 解决conflicts如果merge的结果里有显示conflicts

   6. git commit  //解决冲突后先commit到branchB

   7. git checkout branchA  //切换到targetBranch

   8. git merge --no-ff branchB  //建议merge的时候总是用 --no-ff 选项

   9. git push origin branchA   //把sourceBranch的修改merge到targetBranch之后,push到远程的targetBranch


做git patch文件

先首先先通过git log 查看有哪一些commit,然后在你要把提交的前一个 commitid,git format-patch  commitid,那你的这次提交就是相应对前一次commit 生成的

1 使用git format-patch生成所需要的patch:
当前分支所有超前master的提交:
git format-patch -M master
某次提交以后的所有patch:
git format-patch 4e16 --4e16指的是commit名
从根到指定提交的所有patch:
git format-patch --root 4e16
某两次提交之间的所有patch:
git format-patch 365a..4e16 --365a和4e16分别对应两次提交的名称
某次提交(含)之前的几次提交:
git format-patch –n 07fe --n指patch数,07fe对应提交的名称
故然,提取某一次提交即为:
git format-patch -1 07fe
git format-patch生成的补丁文件默认从1开始顺序编号,并使用对应提交信息中的第一行作为文件名。如果使用了-- numbered-files选项,则文件名只有编号,不包含提交信息;如果指定了--stdout选项,可指定输出位置,如当所有patch输出到一个文件;可指定-o <dir>指定patch的存放目录;

或者:

生成patch   git diff commitID1 commitID2 > patch


2应用patch:
先检查patch文件:git apply --stat newpatch.patch
检查能否应用成功:git apply --check newpatch.patch
打补丁:git am --signoff < newpatch.patch

合入patch :   git apply patch


 遇到的问题记录解决方案:

将完全空白的已建两个项目关联
首先讲一种简单的场景,如果我们新建项目的时候没有生成任何的初始化文件,我们需要做的就是将本地的项目和空白的仓库关联起来,这种情况下的命令是:

#git初始化
git init
#设置remote地址
git remote add 地址
#将全部文件加入git版本管理 .的意思是将当前文件夹下的全部文件放到版本管理中
git add .
#提交文件 使用-m 编写注释
git commit -m "注释"
#推送到远程分支
git push
执行完以上操作,项目就与远程git仓库关联到了一起,可以正常使用了,去git项目页上可以看到刚刚提交的代码


有文件的项目关联
然后就考虑最开始说的情况,就是远程仓库里已经有文件,这时候你执行上面的步骤是不可以的,因为需要把远程仓库的文件先更新下来。步骤如下

#git初始化
git init
#设置remote地址
git remote add  origin 地址
#获取远程仓库master分支上的内容
git pull origin master
#将当前分支设置为远程仓库的master分支
git branch --set-upstream-to=origin/master master
#将全部文件加入git版本管理 .的意思是将当前文件夹下的全部文件放到版本管理中
git add .
#提交文件 使用-m 编写注释
git commit -m "注释"
#推送到远程分支
git push

-------------------------------------------------------------------------------------------------------------------------

把某个commit提交到指定的本地分支和远程分支

1.例子:如我的Git文件在H:盘下,/h/myfirstproject,该目录中有三个分支:test分支,newbranch1分支和mater分支。如果想把test分支的某个commit合并到master,需要经过下面的步骤:
 执行git log -3 --graph test,查看test分支下的commit:    注:commit 后面的hash值代表某个commit,这里把”2e1ada53819d46557b24ee7376dc61d37a06939d“这个commit提交到master。
 执行git checkout master,切换到master分支。

(1.1)执行 git cherry-pick 2e1ada53819d46557b24ee7376dc61d37a06939d,该commit便被提交到了master分支。
到此,”2e1ada53819d46557b24ee7376dc61d37a06939d“这个commit便被提交到了master分支。

(1.2)然后再git push 推送到远程服务器(cherry-pick操作从意义上来说,相当于普通的commit)

2.例子:把本地的test分支的某个commit提交到远程testdevelop分支。

从远程分支 checkout 出来的本地分支,称为跟踪分支(tracking branch)。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入Git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。
 
在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如origin 上除了 master 之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。


1.首先新建一个临时分支,并把临时分支与远程分支关联。
 
git checkout -b tempbarch --track origin/testdevelop
 
2.此时已经切换到了tempbarch分支。再执行:git log -3 --graph test,查看test分支下的commit:
 
3.执行git cherry-pick f6cb436ff5a010cdd72dc2c8ff018db8e8832271 即可把”f6cb436ff5a010cdd72dc2c8ff018db8e8832271“这个commit提交到tempbranch分支。然后再通过push命令,即可把该commit提交到远程testdevelop分支。


4.切换到任何非tempbranch分支,如master分支,执行git branch -d tempbranch,即可把tempbranch分支删除掉


删除误提交到服务中的文件

有时候我们可能会将一些不需要跟踪的文件上传到远程仓库中,例如配置文件等等。为了不影响其他开发者使用git上的代码,我们需要删除已经传到远程仓库中的错误文件。

(1)在本地拉取远程分支 git pull origin master

(2)在本地删除对应的文件:git rm filename(同时在缓存和物理存储中删除文件,慎用),

                                                git rm --cache filename(只在缓存中删除对应的文件, git rm --cached a.txt 删除的是本地仓库中的文件,且本地工作区的文件会保留且不再与远程仓库发生跟踪关系,如果本地仓库中的文件也要删除则用git rm a.txt)

(3)将处理后的工程提价,上传到远程仓库:git commit -m"本地删除远程文件filename"),git push origin master


做git提取包

(1)首先你得知道版本之间的commit id 
git log --pretty=oneline

(2)使用–name-only参数可以只显示文件名。由于commit id 太长 一般复制前面7位 , commitid 最近的在前面,之前的commitid在后面

(3)执行命令:   git diff 61d2112(最近的commitid)  f3c0f99(之前的commitid) --name-only | xargs zip update.zip

执行该命令后有error提示如下:

    zip warning: name not matched: alps/vendor/mediatek/proprietary/packages/apps/Camera2/common/src/com/mediatek/camera/common/utils/CameraUtil.java
    zip warning: name not matched: alps/vendor/mediatek/proprietary/packages/apps/Camera2/host/AndroidManifest.xml
    zip warning: name not matched: alps/vendor/mediatek/proprietary/packages/apps/Camera2/host/src/com/mediatek/camera/CameraActivity.java

zip error: Nothing to do! (update.zip)
这些提示不要管它,继续后面的执行
进入项目根目录切换至对应的分支上, 然后返回至根目录同一目录中(我的的目录是alps,在此次目录中) 手动新建一个update文件夹,执行命令,(提取包会把修改的对应文件对应生成目录复制过来
git diff commitidA commitidB --name-only | xargs -t -i{} cp --parents {} ./update   

\\将 commitA至commitidB这两次提交之间的所有提交提取出来做一个patch文件


以下两命令已亲自验证可以使用

1. 导出最后一次提交修改过的文件

  我一直在使用这个命令定期进行发送给其他人进行审查/整合。这条命令将把近期提交的修改过的文件导出到一个zip文件。

1

git archive -o ../updated.zip HEAD $(git diff --name-only HEAD^)

2. 导出两次提交之间修改过的文件

  同样,如果你需要导出两次提交之间修改过的文件,你可以用这一个。

1

git archive -o ../latest.zip NEW_COMMIT_ID_HERE $(git diff --name-only OLD_COMMIT_ID_HERE NEW_COMMIT_ID_HERE)


以下七条未验证,

3. 克隆一个特定的远程分支

  如果你想从远程仓库克隆特定的一个分支,这条命令对你很有用:

1

2

3

git init 

git remote add -t BRANCH_NAME_HERE -f origin REMOTE_REPO_URL_PATH_HERE 

git checkout BRANCH_NAME_HERE

4. 从无关的本地仓库应用补丁

  如果您需要申请从提交的一些其他不相关的创库到本地存储库,这里是一个快捷的方式:

1

git --git-dir=PATH_TO_OTHER_REPOSITORY_HERE/.git format-patch -k -1 --stdout COMMIT_HASH_ID_HERE| git am -3 -k

5. 检查您的分支变化是是否其他分支的一部分

  cherry 命令可以让你检查你的分支的变化是否存在于其他一些分支之中。它会显示在当前分支相对于给定的分支的修改,用+或-标志提示提交合并与否。+表示不存在,而-表示存在于给定的分支。

1

2

3

git cherry -v OTHER_BRANCH_NAME_HERE 

#For example: to check with master branch 

git cherry -v master

6. 启动一个无历史的新分支

  有时候,你需要启动一个新的分支,同时想摒弃历史信息,例如,你想将代码放在公共领域(开源)又不想共享历史信息。

1

git checkout --orphan NEW_BRANCH_NAME_HERE

7. 在不切换分支的情况下从其它分支检出文件

  下面的命令是从其他分支获取文件,而不用切换分支。

1

git checkout BRANCH_NAME_HERE -- PATH_TO_FILE_IN_BRANCH_HERE

8. 忽略跟踪文件的修改

  如果你工作在一个团队,他们都是工作在同一个分支,你需要频繁的读取/合并文件。但是有时复位了你环境的特定配置,你必须在合并后每一次都再改一下。使用这个命令,你可以忽略更改特定的文件:

1

git update-index --assume-unchanged PATH_TO_FILE_HERE

9. 检查提交的修改是否发布版本的一部分

  这个 name-rev 命令可以告诉你提交相对于最新发布版本的位置。利用这一点,你可以检查你的变化是否发布版本的一部分。

1

git name-rev --name-only COMMIT_HASH_HERE

10. 使用 pull rebase 操作替代 merge

  如果你工作的团队正工作在同一个分支,那么你所要做的获取/合并或经常拉取。分支合并的 git 记录与合并提交时提示功能分支被并入主干。但在多个团队成员工作的同一分支的情况下,经常合并导致在日志中多个合并的消息引起混乱。所以你可以使用 pull rebase,以保持历史信息清除了无用合并的消息。

1

git config branch.BRANCH_NAME_HERE.rebase true

  此外,您可以配置一个特定的分支总是衍合:

1

git pull --rebase 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值