0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gitのrebaseでファイルが復活・先祖返りした話と、安全な戻し方・進め方

0
Last updated at Posted at 2026-03-16

Gitで開発中のブランチを親ブランチに追従させるために rebase したところ、かなり嫌な崩れ方をした。

起きたのはこんな症状だった。

  • 前に消したはずのファイルがステージングに上がる
  • 修正済みのファイルが消えて、古い内容が復活する
  • 階層移動したはずのファイルが、昔の場所で復活する
  • VS Code 上では何が正なのか分かりづらい

最初は VS Code 側の不具合かと思ったが、整理すると本質は Git の rebase による履歴再適用時の衝突だった。

原因として考えられること

今回のような「削除したものが戻る」「移動前のファイルが復活する」は、主に以下で起きやすい。

1. 親ブランチ側でも同じファイルに変更が入っていた

自分は削除・移動したつもりでも、親ブランチ側が古いパスのまま修正していると、rebase 時に古いファイルが再適用されやすい。

2. Git が rename / move をきれいに認識できなかった

Git はファイル移動を厳密に記録しているわけではなく、実質的には「削除 + 追加」として扱うことがある。
そのため、階層移動と中身修正を同時にやると、rebase 時に壊れやすい。

3. 競合解消時に古い側を採ってしまった

VS Code の競合解消は便利だが、Current / Incoming の意味を曖昧に理解したまま進めると、意図せず先祖返りが起きる。
特に rebase 中は感覚がずれやすい。

4. 競合が片付ききっていない状態で add / continue した

git add . でまとめて進めると、不要に復活したファイルまでステージングされやすい。

まずやるべきこと

rebase 中に明らかに壊れたなら、無理に直しきろうとしない方がよい。
未 push なら、まずは rebase 前の状態に戻すのが安全。

rebase の途中ならこれ

git status
git rebase --abort

これで、競合や中途半端なステージングを含めて、rebase 開始前の状態に戻せることが多い。

もし abort できない場合

すでに rebase 自体は終わっていて、履歴だけ書き換わってしまっている可能性がある。
その場合は reflog から rebase 前の地点を探して戻す。

git reflog --date=local
git reset --hard HEAD@{n}

HEAD@{n} は、rebase 開始前の位置を見て選ぶ。

今回の学び

一番大きかったのは、壊れた状態のまま rebase を進めないこと
「とりあえず競合を解消して continue すれば何とかなるだろう」は危険だった。

特に、以下が含まれるコミットは要注意。

  • ファイル削除
  • ディレクトリ移動
  • ファイル名変更
  • import パス変更
  • 中身の大幅修正

これらを一気にやると、rebase でかなり崩れやすい。

今後の安全な rebase 手順

今後は次の流れでやる。

1. 作業ツリーをきれいにする

未コミット変更があるなら stash か commit で退避する。

git status
git stash push -u -m "before rebase"

2. 念のため退避ブランチを切る

git switch feature/xxx
git branch backup/feature-xxx-before-rebase

3. リモート最新を取得

git fetch origin

4. 自分のブランチで親ブランチに rebase

git rebase origin/main

親が develop なら origin/develop にする。

5. 競合したら1件ずつ直す

git status
git diff
git add path/to/file
git rebase --continue

ここで大事なのは、git add . を雑に使わないこと。
ファイル単位で確認して進める方が安全。

6. 変だと思ったら即 abort

git rebase --abort

7. 終わったら差分確認

git status
git log --oneline --graph --decorate -20
git diff origin/main...HEAD

再発防止のために意識したいこと

移動と修正を分ける

安全なのは以下の順番。

  1. ファイル移動だけ
  2. import 修正だけ
  3. 中身修正だけ
  4. 不要ファイル削除

この分け方にすると、Git が履歴を追いやすい。

長期間放置してから rebase しない

親ブランチとの差が広がるほど、競合も崩れ方も重くなる。
細かく追従した方が結果的に楽。

VS Code 任せにしすぎない

競合が起きたら、最終的には git statusgit diff で確認する。
GUI は便利だが、壊れたときの本当の状態は Git コマンドの方が分かりやすい。

まとめ

今回の件で分かったのは、rebase 自体が悪いのではなく、削除・移動・改名・修正が混ざった履歴に対して、曖昧なまま進めると事故るということだった。

そして、壊れたときは慌てて直そうとするより、

  • まず git rebase --abort
  • 戻れなければ git reflog
  • 正常地点に git reset --hard

この順で落ち着いて戻すのが一番安全。

今後は、rebase 前に退避、競合は1件ずつ確認、怪しかったら即 abort の運用に寄せていきたい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?