git push
===
###### tags: `git`, `gitlab`, `git-lab`, `github`, `git-hub`, `push`
<br>
[TOC]
<br>
## 常見 Q & A
### 為什麼 `git push` 會失敗(non-fast-forward)?
> by gpt-5.2 (2026/02/02)
```
$ git push
To ssh://10.0.1.2:30000/my-project/my-service.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'ssh://10.0.1.2:30000/my-project/my-service.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```
- A:因為遠端 `origin/main` 比你本機多 commit,你本機又先做了 commit。此時直接 push 會被拒絕,必須先把遠端更新整合進來(pull/rebase)再推。
- ### Q: `git pull`
```
$ git pull
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
```
為什麼 `git pull --rebase` 說我有 unstaged changes?
- A:因為你工作區有未提交的修改(例如 `config/slurm.key`)。Rebase 需要工作區乾淨,所以要先 **stash** 或 **丟掉變更**。
- ### Q:最簡單的標準解法(保留本機修改、不提交它)怎麼做?
- A:用 stash → rebase → push → stash pop
```bash
git stash -u
git pull --rebase
git push
git stash pop
```
- `-u`, `--include-untracked`, `--no-include-untracked`
When used with the push and save commands, all untracked files are also stashed and then cleaned up with git clean.
> **搭配 `push` 與 `save` 指令使用時**:會把**所有未追蹤檔案(untracked files)**也一併加入 stash,並且接著透過 `git clean` 將這些未追蹤檔案**清理掉**。
When used with the show command, show the untracked files in the stash entry as part of the diff.
> **搭配 `show` 指令使用時**:會在 diff 的內容中,將 stash 項目裡的**未追蹤檔案**也一併顯示出來。
- ### Q:如果我不想保留本機那個修改(直接放棄)?
- A:先丟掉變更,再 rebase/push
```bash
git restore <檔案>
git pull --rebase
git push
```
(例:`git restore config/slurm.key`)
- ### Q:我不想讓某個「本機專用檔」每次都出現在 `git status`?
- A:用 `skip-worktree` 讓它保持本機差異、但不再一直提示
```bash
git update-index --skip-worktree <檔案>
```
要取消:
```bash
git update-index --no-skip-worktree <檔案>
```
- ### Q6:`docs/debug/`、`__pycache__/` 這種檔每次都出現很煩,怎麼辦?
- A:加到 `.gitignore`
```gitignore
docs/debug/
__pycache__/
```
<br>
## 討論
### fatal: You are not currently on a branch.
- ### Question
```
$ git push
fatal: You are not currently on a branch.
To push the history leading to the current (detached HEAD)
state now, use
git push origin HEAD:<name-of-remote-branch>
```
原本 git push 就可以 commit ,為何變成這樣?
- ### gpt-4.1 (2025/08/08)
你出現「fatal: You are not currently on a branch」
這表示**你目前在 detached HEAD 狀態**,不是在任何本地分支上,所以 git 不知道要把 commit 推到哪一個分支。
---
### 為什麼會發生?
常見原因有:
* 你是用 `git checkout origin/xxx`(帶上遠端分支名稱)而不是 `git checkout xxx`(本地分支名稱),這會讓 HEAD 指到某個 commit,而不是分支頭。
* 或你用 `git checkout <commit-sha>`,直接進入 detached HEAD 狀態。
---
### 怎麼解決?
**1. 檢查目前狀態**
```bash
git status
```
你會看到類似:
```
HEAD detached at <commit-sha>
```
---
**2. 重新切回本地分支再 push**
假設你本來要 push 到 `master`:
```bash
git checkout master
git pull # 先同步遠端,避免衝突
git push
```
如果你是要 push 到 `claude/issue-55-d23bc`:
```bash
git checkout claude/issue-55-d23bc
git pull
git push
```
---
**3. 如果本地沒有那個分支,建立本地分支繼續操作**
假設你在 detached HEAD 狀態,
你可以用下面的指令讓你的當前內容變成一個本地分支,然後再 push:
```bash
git checkout -b my-temp-branch
git push origin my-temp-branch
```
---
### 為什麼原本 git push 可以、現在不行?
* **原本你在分支上**(如 `master`),`git push` 會自動推到對應的遠端分支。
* **現在你在 detached HEAD 狀態**,沒有任何分支對應,`git push` 不知道你想推去哪。
* 只要回到分支(`git checkout <branch>`),就會恢復正常。
---
### 總結
* 解法:**切回你的本地分支再 push**
* 或用 `git checkout -b <new-branch>` 再 push
---
你要不要貼一下 `git status` 給我看?
可以幫你分析是從哪個 commit / 分支進到 detached HEAD 的!
<br>
### detached HEAD 怎麼用中文稱呼?
- ### gpt-4.1 (2025/08/08)
「detached HEAD」在中文(尤其是臺灣地區工程師常用語境)通常會翻譯成:
* **分離 HEAD 狀態**
* **游離 HEAD 狀態**
* **HEAD 游離狀態**
* **HEAD 已分離**
其中最常見、最普遍被接受的說法是:
> **分離 HEAD 狀態**
> (英文:detached HEAD state)
或簡稱「**分離 HEAD**」、「HEAD 分離狀態」。
---
### 範例說明
* 你現在是在**分離 HEAD 狀態**,無法直接 push 到遠端分支。
* Git 會顯示「分離 HEAD」或「HEAD 已分離」提示。
---
### 臺灣社群用法
多數教學、書籍、社群討論也都直接寫「分離 HEAD 狀態」。
(有時候保留英文 detached HEAD,因為很難誤解。)
---
如需對一般使用者解釋,可以補充:
> 「分離 HEAD」指的是目前不是位於任何分支,而是直接在某個 commit 上操作的狀態。
---
有需要更多簡單白話的解釋範例,也可以再問我!
<br>
{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}