Quantcast
Channel: 看得透又看得远者prevail. ppt.cc/flUmLx ppt.cc/fqtgqx ppt.cc/fZsXUx ppt.cc/fhWnZx ppt.cc/fnrkVx ppt.cc/f2CBVx
Viewing all articles
Browse latest Browse all 20602

git branch的相关命令

$
0
0


create a branch, add some files, push to remote repository
git branch branchName
echo "Some information"> test.txt
git add test.txt
git commit -m 'add text.txt'
git push origin branchName
list all local branches
git branch -a
checkout remote branch
There is a branch named dev in remote repository, you want to trace that:
git branch -b dev origin/dev
delete remote branch
git push origin --delete 

git push origin :
delete local branch
// -d means --delete
git branch -d branchName

// force delete, even is not merged
git branch -D branchName

Merge & Rebase

Here is a repository has a branch named b1, it has some commits A, B. A -- B [b1]
  1. Local Case A:
    You check out b1, then do some work, your commit is C, after your commit, your local repository will be:
    A -- B -- C      [b1]
  2. Local Case B:
    You create branch b2 from b1, then commit.
    A -- B      [b1]
    \
    C [b2]
  3. Local Case C:
    You did nothing. A -- B [b1]
  4. Remote Case A:
    At the same time, someone commited a change, namely commit D, pushed the commit to repository server.
    A -- B -- D         [remote b1]
    \
    ----- C [local]
  5. Remote Case B:
    No commit has been pushed to remote before you push commit C to remote. The remote remains:
    A -- B   [b1]
$ git st
# On branch develop
# Your branch and 'origin/develop' have diverged,
# and have 1 and 2 different commit(s) each, respectively.
#
nothing to commit (working directory clean)
git fetch
After git fetch, your local repository will be one of the following status:
Case A: Local Case A + Remote Case B

A -- B [b1]
\
C [b1]

Case B: Local Case B + Remote Case B

A -- B [b1]
\
C [b2]

Case C: Local Case C + Remote Case A

C [b1 remote]
/
A -- B [b1,local]

Case D: Local Case A + Remote Case A

A -- B -- D [b1]
\
---- C [b1]

Case E: Local Case A + Remote Case B

A -- B -- D [b1]
\
--- C [b2]
what is fast-forward
If the branch has not diverged, and HEAD is behind, it can do fast-forward.
If git merge is called on a branch which can fast-forward, fast-forward will be applied automatically
git merge --ff-only origin/master will try to use fast-forward, abort if fast-forward is not possible.
git merge in one branch
$ git merge
After merged:
Case A: do nothing
Case B: do nothing
Case C: Fast-forward will be applied

A -- B -- C [b1,local/remote]


Case D: Merge, a new commit `E` will be created automatically.

A -- B -- D --- E [b1]
\ /
---- C [b1]
git merge two branches
$ git merge origin/b1
After Merged:
Case E:
A -- B ------ D [b1]
\ \
-- C -- E [b2]
git pull
git pull = git fetch + git merge
git rebase in one branch
# Case E
$ git rebase
A -- B ------- D [b1,remote]
\
------ D -- C1 [b1,local]
git rebase in diffrent branches
# Case F
$ git rebase origin/b1

A -- B ------- D [b1,remote]
\
------ D -- C1 [b2,local]
git push force
Why?
Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it.
Case F, may need force push. If b2 has some pushed commits before D and C
         pushed
A -- B -..... --- D [b1,remote]
\
-.... --- D -- C1 [b2,local]
$ git push origin b2 -f
$ git push origin b2 --force
$ git push origin +b2 
------------------
 

Git分支操作 

本文介绍日常中经常遇到的一些分支操作,并给出了详细解释。
  • 创建分支;
  • 删除分支;
  • 检出远程分支;
  • git merge;
  • git rebase;
  • git force push;
  • git fast-forward.

分支简单操作

最简单的用法
创建一个分支,添加文件,提交,推送。但是日常工作中往往比这个复杂得多。
git branch branchName
echo "Some information"> test.txt
git add test.txt
git commit -m 'add text.txt'
git push origin branchName
列出所有分支
git branch -a
检出一个远程分支
远程有一个 dev分支,你想 check out 这个分支到本地:
git branch -b dev origin/dev
开发告一段落,你把远程一些没用的分支删除:
git push origin --delete 

git push origin :
删除本地分支:
// -d 是 --delete 选项的短选项
git branch -d branchName

// 强制删除
git branch -D branchName

Merge & Rebase

git pull是非常笼统的一种操作,下面我们分析日常所有可能遇到的情况:
假设代码库有一个分支 b1, 当前有两次提交: A, B,如下: A -- B [b1]
  1. 本地可能发生的操作 A:
    你检出 b1,修改了代码,然后提交,生成一个提交:C
    A -- B -- C      [b1]
  2. 本地可能的情况 B:
    你从b1建了一个新的分支 b2, 提交代码,生成一个提交:C
    A -- B      [b1]
    \
    C [b2]
  3. 本地可能的情况 C:
    本地代码无任何变动。嗯,这也算情况之一。 A -- B [b1]
  4. 现在让我们看看远程的集中情况
    远程情况 A:
    在提交代码的期间,有人推送代码到了分支b1, 这个提交称为:D
    A -- B -- D         [remote b1]
    \
    ----- C [local]
  5. 远程情况 B:
    远程情况没任何变动。
    A -- B   [b1]

在上面,A, B, C, D指代可以是一次提交,也可以是一系列提交。

git fetch
现在你将远程变动取到本地,这时,本地代码库有可能以下几种情况:
Case A: 本地情况 A + 远程情况 B

A -- B [b1]
\
C [b1]

Case B: 本地情况 B + 远程情况 B

A -- B [b1]
\
C [b2]

Case C: 本地情况 C + 远程情况 A

C [b1 remote]
/
A -- B [b1,local]

Case D: 本地情况 A + 远程情况 A

A -- B -- D [b1]
\
---- C [b1]

Case E: 本地情况 A + 远程情况 B

A -- B -- D [b1]
\
--- C [b2]
以上5种情况,就是我们日常中经常遇到的情况。

什么是: fast-forward
git fetch之后,如果本地分支和远程分支没有分叉,并且本地分支指向较旧脚本,那么,这个分支称为可以 fast-forward;
fast-forward时,本地分支把指针指向最新的提交,并不会生成一个提交。
如果分支可以 fast-forward,执行 git merge时,实际执行的是fast-forward。如果不能,则合并,并自动产生一个提交。
很多情况下,我们并不希望有这样的自动合并产生,因为他产生了一个自动提交,会让版本变得交叉,不清晰。
我们希望,能 fast-forwardfast-forward, `,否则我们用rebase命令合并。可以这样:
git merge --ff-only origin/master
如果不能 fast-forward, merge 操作会终止。

git merge 合并一个分支
$ git merge
操作之后:
Case A: 没变化
Case B: 没变化
Case C: fast-forward

A -- B -- C [b1,local/remote]


Case D: 合并,并且自动生成一个提交E

A -- B -- D --- E [b1]
\ /
---- C [b1]
git merge 合并两个分支
当前在 b2上,合并远程 b1的改动,对应 Case E
$ git merge origin/b1
合并之后 :
Case E:
A -- B ------ D [b1]
\ \
-- C -- E [b2]

图1
git pull
git pull = git fetch + git merge
git rebase
只有当一个分支出现分叉,或者在不同的分之间,git rebase 才有意义。命令格式:
git rebase 目标分支
在git rebase时:
  1. 把本地未推送的所有提交,放到暂存区。
  2. 然后将本分支的指针指向目标分支最新提交,即改变本地分支的基础,简称变基, 这个翻译真是太糟糕了。
  3. 然后将暂存区的本地未推送的提交挨个应用回本分支。
同一个分支的 rebase
# Case E
$ git rebase
A -- B ------- D [b1,remote]
\
------ D -- C1 [b1,local]

图2
先将本地的提交 C暂存,然后指向 D, 应用 CCD之前,变成了 C1。注意这个和上面 egit merge(图1)的区别。
不同分支的 rebase
这其实和同一个分支类似,不过注意,不同分支 rebase 可能需要强制推送:
# Case F
$ git rebase origin/b1

A -- B ------- D [b1,remote]
\
------ D -- C1 [b2,local]
强制推送: git push --force
为什么需要强制推送,官方文档:
Usually, the command refuses to update a remote ref that is not an ancestor of the local ref used to overwrite it.
Case F, 如果b2DC之前,有其他的提交已经推送到服务器了,则需要强制推送,因为他们是从 B开始分叉的。
         pushed
A -- B -..... --- D [b1,remote]
\
-.... --- D -- C1 [b2,local]
.
$ git push origin b2 -f
$ git push origin b2 --force
$ git push origin +b2 
--------------------
 

Some tips for git setup and git config

the ssh key

generate ssh key
cd ~/.ssh/
ssh-keygen -t rsa -C "changeme@xxx.com" -f filename
If the options f is not input, the file name of the public/pirvate rsa key pair files will be: id_rsa, id_rsa.pub.
add ssh key
ssh-add ~/.ssh/xxx
list all added ssh key
ssh-add -l
you may run into this error when try ssh-add:
Could not open a connection to your authentication agent.
eval `ssh-agent -s`
add ssh key permanently
Add the key path to ~/.ssh/config
$ vim ~/.ssh/config

IdentityFile ~/.ssh/gitHubKey
IdentityFile ~/.ssh/xxx

git config

global config & repository config
The global setting is stored in ~/.gitconfig
The config of repository is stored in ./.git/config, in the repository directory.
git config --global will use global config, without --global options will use try to use the config file ./git/config in current directory.
config user name & user email for every repository
You may work with multiple repositories, so it is a good practice to config user information for every repository.
# for global setting
git config --global user.name xxx
git config --global user.email xxx@xxx.com

# for repository
git config user.name xxxx
git config user.email xxxx@xxx.com
git alias
Setup alias for convenience.
#git st => git status
git config --global alias.st 'status'

#git co => git checkout
git config --global alias.co 'checkout'

#git lg to view commit log like network graph
git config --global alias.lg "log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset' --abbrev-commit"

#...
# whatever you like 
--------------------
 

git配置问题: 多个 sshkey, 多个用户身份, git alias 

ssh key

生成sshkey
cd ~/.ssh/
ssh-keygen -t rsa -C "changeme@xxx.com" -f filename
如果没有指定 f选项或者 f选项为空,生成的私钥和公钥为: id_rsa, id_rsa.pub.
添加 sshkey
ssh-add ~/.ssh/xxx
列出所有的 sshkey
ssh-add -l
执行 ssh-add可能会遇到的问题:
Could not open a connection to your authentication agent.
解决办法:
eval `ssh-agent -s`
机器重启又得重新添加 sshkey,如何永久添加 sshkey
把 sshkey 私钥的路径加入到 ~/.ssh/config, 如下:
$ vim ~/.ssh/config

IdentityFile ~/.ssh/gitHubKey
IdentityFile ~/.ssh/xxx

git config

全局配置和项目配置
全局配置信息在: ~/.gitconfig
项目配置在项目目录下的: ./.git/config
git config --global操作全局配置, 不带 --global选项的话,会尝试相对于当前目录的: ./git/config, 找不到的话,报错。
为各个项目单独配置user.nameuser.email
你可能会在不同的几个项目中工作,各个项目的用户名可能不同,为了保证日志的准确性和提交时无误,最好对各个项目设置 user.nameuser.email
# for global setting
git config --global user.name xxx
git config --global user.email xxx@xxx.com

# for repository
git config user.name xxxx
git config user.email xxxx@xxx.com

git alias

使用快捷命令能带来很方便,输入命令更加快速,git lg这个短命令配置,将日志图形化方式展现:
#git st => git status
git config --global alias.st 'status'

#git co => git checkout
git config --global alias.co 'checkout'

#git lg to view commit log like network graph
git config --global alias.lg "log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%ci) %C(bold blue)<%an>%Creset' --abbrev-commit"

 

 

 

 

 


Viewing all articles
Browse latest Browse all 20602

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>