---
# System prepended metadata

title: git push
tags: [push, git-lab, github, git-hub, git, gitlab]

---

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 %}