git 日常操作笔记

基本概念

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

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

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

 

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

git-repo

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

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

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

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

配置个人的用户名称和电子邮件地址:

$ git config --global user.name "xxxx"
$ git config --global user.email [email protected]

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

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

文本编辑器

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

$ git config --global core.editor emacs

差异分析工具

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

$ git config --global merge.tool vimdiff

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

初始化一个Git仓库,使用git init命令。

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

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

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

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

用git status告诉你有文件被修改过,

git diff可以查看修改内容。

git push 命令讲解

关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git

关联后,使用命令git push -u origin master第一次推送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

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

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

1

$ git push origin

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

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

1

$ git push

如果当前分支与多个主机存在追踪关系,则可以使用-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分支。

如果当前分支与远程分支存在追踪关系,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

解释--

这个命令做了以下内容: 
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 常用命令速查

首先 知道git上项目的地址 ,然后挡到本地

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

最常用的  git pull  //更新

git add readme 文件名(例如:git add readme demo.php)         //代码上传到服务器

git status   //查看项目当前状态


git branch 查看本地所有分支

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

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

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

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

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

git status 查看当前状态 
git commit 提交 

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 将本地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 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 -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 显示工作目录与索引文件之间的差异

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 HEAD -- readme.txt命令可以查看工作区和版本库里面最新版本的区别:

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

查看尚未暂存的某个文件更新了哪些 git diff –cached       

查看已经暂存起来的文件和上次提交的版本之间的差异 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 [email protected]: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 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 reset --hard和git clean -f是一对好基友. 结合使用他们能让你的工作目录完全回退到最近一次commit的时候


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 --pretty=oneline    oneline 将每个提交放在一行显示,这在提交数很大时非常有用。另外还有 shortfull 和 fuller 

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

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

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

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

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 checkout file取消到工作目录中文件的修改

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

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

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

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


【本地代码库回滚】:

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

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

【远程代码库回滚】:

git reset --hard HEAD^ | git reset --hard <版本号> 先回滚本地的代码

git push origin master --force 会提示本地的版本落后于远端的版本 所以得加参数--force   强制提交


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

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


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

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的存放目录;


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

猜你喜欢

转载自blog.csdn.net/nei504293736/article/details/89439466