Posts tagged with “git”

Git Tips: Remove tracking branches no longer on remote

My colleage Joe asked me tonight, "how to remove those branches that no longer exist on remote?"

In short, you have two options

  1. run git remote prune origin at times
  2. run git config --global fetch.prune true command to config your git to delete those branches every time when you run git fetch

I prefer the second option, how about you?

Reference

神奇且无害的REBASE

2014年底翻译了这篇文章,当时发表在GotGit 群组,搬过来留存一下

作者:Jeff Kreeftmeijer 发表于 2010-10-11 原文链接

大约一个月前, 以Git为主题我写了不少文章,始于@nvie 出色的git开发流程教你写出更好的提交注释,终结于强大的reflog和惊人强大的bisect 。你猜怎么着?我竟然忘记了介绍神奇的rebase

人们通常认为rebase是一种压合提交工具,但这并非它的看家本领。顾名思义,它的本职工作是变基(改变我们所做变更的基础)。

哦,忘掉那篇吓唬人的文章,只要清楚自己在做什么,根本不会产生什么恶果。

假设你正工作在一个名叫feature/login的新功能分支上,某个家伙实现了某样东西,并把他的代码push到了develop分支上。你需要那个东西,该怎么做?

可以把develop分支合并到你正在工作的分支,这会产生一些....乱七八糟的合并提交,不好。

也可以把我们需要的那个提交cherry-pick过来。不过--经验表明--虽然不是什么大问题,从一堆提交里找出需要拣选的提交,终究是个麻烦事。

Git的rebase指令允许我们先回退自己的改动(类似“倒带”),拉回另一个分支的所有变动之后(变基),在新的基础(HEAD)上“重放”我们的变更:

$ git rebase develop

First, rewinding head to replay your work on top of it...
Fast-forwarded feature/login to develop.

仿佛在拉回那些变更之前,我们什么也没做(我们所有的改动仿佛发生那些变更之后)。这非常好,是不是?我们还能在pull的同时变基(使用--rebase选项),这样的话我们甚至都不需要离开自己的工作分支。

更小块的冲突

rebase让我们拥有干净的提交历史,即便在rebase的过程中发生冲突,它也是我们解决冲突的坚强后盾:

$ git rebase develop
First, rewinding head to replay your work on top of it...
Applying: feature/login
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging config/environment.rb
CONFLICT (content): Merge conflict in config/environment.rb
Failed to merge in the changes.
Patch failed at 0001 feature/login

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

由于rebase顺序重放每一个提交,冲突会以更小的块(更多的次数)出现,这有助于我们迅速理解冲突原因,更快地解决冲突。在解决冲突之后,只需git add冲突文件,然后输入下面的命令继续rebase过程:

$ git rebase --continue

rebase 还是 merge

当我们工作于一个功能分支,发现需要 develop 分支上的所有变更时,我建议使用rebase。当我们的功能分支已经开发完成,应该使用 merge 把功能分支合并回 develop分支。这样我们能够记录下我们在何时把分支合并到 develop 主干,就是利用那个...我们前面说过的“乱七八糟”的提交。在这个时候,它真的不是乱七八糟的提交,确实不是。

在合并功能分支之前,我希望你使用rebase。这样我们方能保证自己的分支在合到并主干时仍然拥有干净的提交历史。

你用过rebase吗?你在何时使用 rebase 不用 merge?还是只用 rebase?你还害怕rebase吗?欢迎撰写评论留下你的想法,让我知道。

PS: 这篇文章虽然写于2010年,但写的清晰明快。我今天(2014年)把它翻译过来,希望能帮助到更多的人。rebase是一个很好的工具,只要你愿意了解它。

Tips collection

  • Buefy is a lightweight UI components library for Vue.js based on Bulma
  • @keyup.enter="eventHandler" doesn't work in el-input, but @keyup.enter.native="eventHandler" does. #element-ui
  • git rm -rf . && git clean -fxd is the best way to delete all files except .git directory. #git
  • To make your dynamic LINQ query safe, you must use placeholders for all user input. Never concatenate your string! #dotnetcore
  • try_files $uri $uir/ =404; is better than try_files $uri $uri/ /index.html;, because it can avoid endless loop when /index.html doesn't exist. #nginx
  • git tag -n99 show tags along with annotations Reference
  • new crontab task added
    0 6 * * * /bin/docker container prune -f 
    10 6 * * * /bin/docker rmi $(/bin/docker images -f "dangling=true" -q)
    

A guide for git status change

状态标识

标志含义
nul文件已提交到版本库未做修改
??untracked 新文件尚未 git add
Astaged 已经 git add 但尚未提交
AMstaged 未提交又做限新的修改,新修改尚未staged
MM一些修改staged之后又做了新的修改,新修改尚未staged

状态转换指南

状态A -> 状态B需要的操作
nul -> M修改文件
MM -> nulgit checkout HEAD file(s) OR git checkout -- file(s)
A -> ??git rm --cached file(s)
M -> Mgit add file(s)
A -> AMgit reset file(s)
A -> nulgit reset file(s)
?? -> Agit add file(s)
A -> ??git rm --cached file(s)
A -> AMgit add 之后再修改文件
AM -> Agit checkout -- file(s)

`git rm --cached ` is a worse choice than `git update-index --assume-unchanged `

There are 3 options, you probably want #3

  1. This will keep the local file for you, but will delete it for anyone else when they pull.

    git rm --cached <file-name> or git rm -r --cached <folder-name>

  2. This is for optimization, like a folder with a large number of files, e.g. SDKs that probably won't ever change. It tells git to stop checking that huge folder every time for changes, locally, since it won't have any. The assume-unchanged index will be reset and file(s) overwritten if there are upstream changes to the file/folder (when you pull).

    git update-index --assume-unchanged <path-name>

  3. This is to tell git you want your own independent version of the file or folder. For instance, you don't want to overwrite (or delete) production/staging config files.

    git update-index --skip-worktree <path-name>

It's important to know that git update-index will not propagate with git, and each user will have to run it independently.