git push在處理branch name的小技巧

把程式丟到heroku跑的話預設是要用master才會run/build你的app,不過有些東西其實不適合放到master branch,例如cdnjs/new-website理面的meta data,之前因為用機器人(其實只是crontab)去更新這些資料,生了上萬個commits出來,多了一堆不必要的log,也淡化contributors list理面真正的contributors的貢獻量

剛剛花了一些時間把那些commits通通清掉,現在大概剩下兩百出頭的commits,雖然還是有一些沒拔乾淨,不過已經無傷大雅了,接下來的meta data就會丟到meta這個branch,不過問題來了,把這些資料直接push到heroku上面(因為一些原因所以不是用GitHub webhook而是自己push)會得到這樣的訊息:

Pushed to non-master branch, skipping build.

目前想的到最簡單的解決方法是這樣:
git push heroku meta:master

也就是在branch名稱後面多了一個:master,意即把本機的meta分支push到heroku這個remote上的master branch

同理也可以在pull的時候這樣做:

git pull upstream master:base

意即把upstream上面的master分支拉到local的base分支上

然後 … 就沒有然後了,滿簡單好用的方法@@

 

Git repository 中,檔案名稱大小寫的重新命名

先前以為 Git 對於檔名的處理是不區分大小寫的(case-insensitive),後來發現其實 Git 是會區分檔名大小寫的,只是作業系統和檔案系統就不一定是這樣了

例如 FAT 檔案系統本身是不區分大小寫的,Mac OS 使用的 HFS+ (或叫做 Mac OS Extended) 雖然支援區分檔名大小寫,但 Mac OS 預設沒有啟用區分大小寫,要重新格式化磁碟為有區分大小寫的檔案系統才行,至於 NTFS 雖然有支援區分大小寫,但 Windows 預設的行為也是不區分大小寫的,所以結論幾乎可以說是在 Mac OS 和 Windows 系統上,檔案系統預設都是不區分大小寫的果然還是用 Linux 或 FreeBSD 比較簡單

如果只是把檔名從 program.cs 改為 Program.cs,用 git status 指令看狀態時會看不到任何改變:

~/test $ git status
On branch master
nothing to commit, working tree clean

~/test $ mv program.cs Program.cs

~/test $ git status
On branch master
nothing to commit, working tree clean

如果自己動手 git mv 呢?有可能會遇到 destination exists 這個問題:

~/test $ git mv program.cs Program.cs
fatal: destination exists, source=program.cs, destination=Program.cs

在網路上有看到一種作法,先將檔案改為另外一個沒有完全相同字母的檔名,再改為目標檔名,藉此替換大小寫:

~/test $ git mv program.cs program.temp && git mv program.temp Program.cs

不過這也太累了,後來發現加上 --force (-f) 的參數就可以搞定這問題了:

~/test $ git mv -f program.cs Program.cs

這時候再用 git status 看狀態就會發現 git 已經可以成功識別重新命名了:

~/test $ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    program.cs -> Program.cs

關於 git mv--force 參數說明是這樣的:

Force renaming or moving of a file even if the target exists

看來只能暫時這樣處理了,用到的機會目前看起來也不是很多就是了~

註:在新版(明確是哪個版本就沒去追了)的 git 直接用 git mv 操作的看起來已經沒問題了,不需要加 -f 也不需要兩段式操作了,讚!

設定 git 的 http proxy

之所以要用這個設定的來由是 … 用習慣自己架設的 git server 會覺得 GitHub 的速度很慢,尤其是要 clone 一個大專案下來的時候就是要等,但是在美國的虛擬主機跑起來速度卻是挺快的,主要應該是網路路由問題(網路環境連某些國家慢、某些很快)

剛好有在某主機上面跑 http proxy 服務,所以就查了一下 git 要怎麼設定 proxy server 來”繞路”,其實還滿簡單的

只要在想要吃這個設定的專案下面跑一行設定:

git config http.proxy http://myusername:mypassword@proxy.server:port

沒有使用者認證的話就把小老鼠(@)前面的那一串拿掉就好了:

git config http.proxy http://proxy.server:port

如果你的所有專案都是在 GitHub 上的話可以乾脆設為使用者的全域設定:

git config --global http.proxy http://proxy.server:port

收工搞定!速度真的差超多~

所以現在都習慣 clone Github 上專案拉下來的時候都走 https 過 proxy,如果有 fork 要 push commit 的話再自己去把 push url 改走 ssh 協定~

更新從 GitHub 上 fork 出來的 repository (或是同步兩個不同 server 端的 repository)

從 GitHub 上面 fork 出來的 repository,整個狀態會停留在當初 fork 的時候,後面的同步要靠自己動手,當然你也可以把 fork 出來的 repository 整個砍掉重新 fork,這邊要講的是手動同步、而不用砍掉重練的方法,有兩個不同的 git server 要做同步的動作也是這樣做,有些專案會同時丟在自己的 git server 跟 GitHub 上,就會需要用到

大致講一下流程 … 操作必須是在自己 local 端做 (希望以後 GitHub 可以推出按一個鈕就幫我去同步到最新XD),做法是把 fork 出來的 repository 在本地更新後、再把 repository 給 push 出去!會需要用到 git 的 branch, remote, pull, push 觀念。

接下來的操作環境是你已經把你 fork 出來的 repository 給 clone 到自己的電腦上了, clone 好之後請切換到對應的資料夾底下,然後就可以開始使用 git 做操作了。

第一次操作時我們要加入一個遠端的 remote 當作更新來源,如果要比較是否有加入成功的話可以在操作前後先看狀態:

$ git remote -v

預設應該只會有 origin 這個 remote:

origin https://github.com/user/repo.git (fetch)
origin https://github.com/user/repo.git (push)

我們用下面這個命令來加入遠端的 repository,在這邊的情境也就是比較新的、上游的 repository upstream 是 remote name、可以自己取名,不要重複就好,但後面我都用會 upstream 做示範,而後面那串網址是 repository 位置:

$ git remote add upstream https://github.com/otheruser/repo.git

如果再看一次現有的remote端應該會發現多了兩組 upstream (fetch & push):

$ git remote -v
 origin https://github.com/user/repo.git (fetch)
 origin https://github.com/user/repo.git (push)
 upstream https://github.com/otheruser/repo.git (fetch)
 upstream https://github.com/otheruser/repo.git (push)

有了遠端的來源後我們就可以開始做更新了

假如我要做更新的的 branch 是 master 的話就先切到 master branch:

$ git checkout master

接著把 upstream 的 master 更新給拉進來

$ git pull upstream master

如果你的 master branch 有自己的 commit, 也可以用 rebase 來避免不必要的 merge 操作:

$ git pull --rebase upstream master

如果沒有發生衝突的話這樣應該就完成了本地的更新,再把更新後的 branch push 出去就行了:

$ git push origin master

這時再回去看看你的 repository 頁面,應該會發現已經同步到最新的狀態了!

Reference:
https://help.github.com/articles/syncing-a-fork