Git

1. Create a code review in Gerrit and push to master branch:

git push origin HEAD:refs/for/master

2. Push the code to Gerrit sandbox without code review:

git push origin HEAD:refs/heads/sandbox/xxx

3. Delete the last pushed commit in the remote branch:

git push origin +HEAD^:master # HEAD can be replaced by commit number

4. Apply patches to the git repository:

patch -p1 < xxx.patch 
# OR 
git apply xxx.patch

5. Merge branch committed before the current master is merged:

git fetch origin 
git checkout -b your_branch 
origin/your_branch 
git fetch origin 
git checkout origin/master 
git merge --no-ff your_branch 
git push origin HEAD:your_branch

6. Delete local or remote branch:

# Delete remote branch: 
git push origin --delete <your_branch> 
# Delete local branch (1): 
git branch -D <branch_name> 
# Delete local branch (2): 
git branch --delete --force <branch_name> 
# same as -D 
# Delete local branch (3): 
git branch --delete <branch_name> # error on unmerge

7. What does “origin” means in Git?

In Git, “origin” is a shorthand name for the remote repository that a project was originally cloned from.

For example, if you clone the repo using: git clone https://repo.link, then “origin” represents https://repo.link.

8. Fork a public repository to private

(Option 1) Create a new GitHub repository by importing from the public repository using the GitHub GUI.

(Option 2) Create a blank private repo and push the public repo as a mirror:

git clone --bare https://github.com/exampleuser/public-repo.git
cd public-repo.git
git push --mirror https://github.com/yourname/private-repo.git

To download the updates from the public repo:

cd private-repo
git remote add public https://github.com/exampleuser/public-repo.git
git pull public master # Creates a merge commit
git push origin master

We can check the remote sources by:

git remote -v 

The result looks like:

origin	https://github.com/dreamibor/mlpractical.git (fetch)
origin	https://github.com/dreamibor/mlpractical.git (push)
public	https://github.com/CSTR-Edinburgh/mlpractical.git (fetch)
public	https://github.com/CSTR-Edinburgh/mlpractical.git (push)

The result also explains what does the keyword origin represent.

Source: https://stackoverflow.com/questions/10065526/github-how-to-make-a-fork-of-public-repository-private/

9. Git Submodule

Add a new remote repository:

git submodule add https://github.com/xxx.git

Update submodules:

git submodule update --remote --recursive

Remove submodules:

git submodule rm xxxx

10. Git – set-upstream

I always use the following command line to push my branch to the repo:

git push -u origin your_branch

However, I am not sure what does -u mean exactly, even after I checked the poor document for Git.

It turns out that -u is a shorthand flag for –up-stream or –up-stream-to, and it’s doing:

It sets the default remote branch for the current local branch (sets the branch you are pushing to as the remote tracking branch of the branch you are pushing).

Any future git pull command (with the current local branch checked-out), will attempt to bring in commits from the <remote-branch> into the current local branch.

Reference: StackOverflow – What does ‘–set-upstream’ do?

11. Git – Rebase your branch when master changed

git checkout master
git pull
git checkout <your_branch>
git merge --strategy-option theirs master
git push -u origin <your_branch>

我们首先需要切换到 master 分支,并将最新的 repo 拉到(pull)本地,然后切换回自己的 branch,将该 branch 的内容与 master 进行合并, 最后将更新 push 到远端。

12. Git Rebase versus Merge

Git has two utilities that specializes in integrating changes from one branch onto another: git rebase and git merge.

假设我们工作在某一个 branch 之上(如此处的 feature 分支),但是另一个团队成员将现在的 master 分支进行了修改(更新了新的 commits)。这样就造成了一个分叉的历史,如下图所示:

A forked commit history

假设 master 中的新 commits 与我们当前的分支有关,则如果要将 master 中的新的 commits 集成到我们当前的分支中,则我们有两个选项:merging 和 rebasing。

12.1 Merge

我们可以将 master 分支 merge 到当前的分支(feature):

git checkout feature
git merge master

或者直接:

git merge feature master

这样我们创建了一个新的 merge commit,其将 master 分支和当前分支的历史结合,得到的新分支的结构如下:

Merge master into the feature branch

Merging 的好处是其不具有毁坏性(non-destructive),现存的分支都没有被改变。

但是坏处是,每次我们要将代码集成到上流(upstream)的时候,都会有额外的 merge commit,这会使得当前分支的历史看起来比较乱。

此外,我们还可以使用 Git Merge Strategy Options

Merge 就是将两个分支合并,Git 尝试在两个或多个 commit 指针中找出共同的 base commit,要找出 base commit,我们需要“合并策略(merge strategies)”。

Merge commit 就是一个一般的 commit,但是其有两个父 commits。

git merge 可以自动选择合并策略,除非我们进行指定,我们可以传入 -s 变量来指定合并策略。

Recursive

git merge -s recursive branch1 branch2

Recursive 是在 pulling 或 合并一个分支的时候的默认参数。

Ours

git merge -s ours branch1 branch2 branch

The Ours strategy operates on multiple N number of branches. The output merge result is always that of the current branch HEAD. The “ours” term implies the preference effectively ignoring all changes from all other branches. It is intended to be used to combine the history of similar feature branches.

Theirs

The opposite of the ‘ours’ strategy. the “theirs” option favors the foreign merging tree in conflict resolution.

git merge --s theirs master

12.2 Rebase

我们还可以降 feature 分支 rebase 到 master 分支之上:

git checkout feature
git rebase master

这样会将整个 feature 分支移到 master 分支的前面,并将 master 中的所有 commits 集成到当前的分支。但是 rebase 并不是创建新的 merge commit,而是重新项目的历史,为每一个原分支中的 commit 重新创建新的 commits。

Rebasing

Rebase 的好处是我们可以得到一个更干净的项目历史(线性的项目历史,并不像 merge 从两个分支合并)。

但是 rebase 有两个潜在的问题:

  1. 安全性 – 如果不遵循 rebasing 的准则,那么重写项目历史是很危险的。
  2. 可溯性(traceability)- 丢失了 merge commit 的上下文,不知道上流的分支是何时与当前分支合并的。

Interactive Rebasing

我们可以运行交互性的 rebasing 程序:

git checkout feature
git rebase -i master

此时会打开一个文本编辑器,我们可以任意调整 commit 的顺序、合并。

Rebasing 的黄金法则

千万别在公共的分支上应用 git rebasethe golden rule of git rebase is to never use it on public branches),如将 master 分支 rebase 到自己的分支之上。

Wrong – rebasing the master branch

So, before you run git rebase, always ask yourself, “Is anyone else looking at this branch?” If the answer is yes, take your hands off the keyboard and start thinking about a non-destructive way to make your changes (e.g., the git revert command). Otherwise, you’re safe to re-write history as much as you like.

Reference:

  1. Git rebase
  2. Git merge