Bagaimana cara menghapus komit pertama di git?

179

Saya ingin tahu tentang cara menghapus komit pertama di git.

Apa revisi sebelum melakukan sesuatu? Apakah revisi ini memiliki nama atau tag?

Jian Weihang
sumber
2
Untuk memulai dengan git, Anda harus tahu bahwa revisi tidak ada artinya. Anda dapat berbicara tentang komitmen atau SHA relatif mereka. Juga, mengapa Anda ingin melakukan ini? Komit pertama adalah apa yang dibangun di atas segalanya. Anda bisa memecah beberapa komit bersama, termasuk komit pertama, yang menjadi komit pertama yang baru, tetapi apa artinya bahkan menghapus komit pertama (atau menghapus komit terakhir)?
Shahbaz
@ Shahbaz ya, itulah cara terbaik, lihat di sini misalnya: ariejan.net/2011/07/07/05/git-squash-your-latests-commits-into-one
timaschew
5
Anda bisa menggunakannya git rebase -i --root. Lihat jawaban SO berikut untuk detailnya: stackoverflow.com/questions/2246208/…
MKroehnert
kemungkinan duplikat Bisakah saya menghapus komit awal dari repo Git?
Gordon Gustafson
Jawaban ini memiliki solusi yang tepat untuk menghapus root commit dari cabang saat ini:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon

Jawaban:

321

Bagi saya, cara paling aman adalah menggunakan update-refperintah:

git update-ref -d HEAD

Ini akan menghapus referensi yang disebutkan HEAD, sehingga akan mengatur ulang (dengan lembut, Anda tidak akan kehilangan pekerjaan Anda) semua komit Anda dari cabang Anda saat ini .

Jika yang Anda inginkan adalah menggabungkan komit pertama dengan komit kedua, Anda dapat menggunakan rebaseperintah:

git rebase -i --root

Cara terakhir adalah membuat cabang yatim, cabang dengan konten yang sama tetapi tanpa riwayat komit, dan mengkomit konten baru Anda di dalamnya:

git checkout --orphan <new-branch-name>
tzi
sumber
7
Sayang sekali ini bukan jawaban yang diterima. Ini juga sangat buruk bahwa sebagian besar hit di google lebih atau kurang mengatakan "Anda tidak dapat membatalkan komit pertama". Ini berhasil bagi saya. Terima kasih!
danielpops
1
Terima kasih @anielops untuk dukungan Anda! Adalah baik untuk memperhatikan bahwa saya menjawab pertanyaan ini 3 tahun kemudian. Git telah berevolusi saat ini.
tzi
Saya menggunakan rebase, menandai komit kedua sebagai "squash", dan kemudian melakukan push - force to origin. Terima kasih!
Philip Atz
1
git update-ref -d HEAD adalah cara paling aman untuk menghapus semua histori, bukan hanya commit awal.
user1767316
Saya melakukannya dan menghapus semua file yang saya tambahkan ke komit pertama. Sedih. Setidaknya itu tidak banyak
Vyacheslav Tsivina
42

Tidak ada apa pun sebelum komit pertama, karena setiap komit merujuk komit orang tua. Ini menjadikan komit pertama spesial (komit anak yatim), jadi tidak ada cara untuk merujuk ke "keadaan" sebelumnya.

Jadi, jika Anda ingin memperbaiki komit, Anda bisa git commit --amend: ini akan memodifikasi komit tanpa membuat komit lainnya.

Jika Anda hanya ingin memulai dari awal, hapus .gitrepositori, dan buat yang lain dengangit init

CharlesB
sumber
7
Jawaban ini salah: ADA cara untuk kembali ke keadaan sebelum komit pertama. Lihat jawaban tzi di bawah ini.
David Nelson
2
The --amendjuga tidak akan memperbarui penulis baik jika awalnya terkonfigurasi. Itulah yang saya butuhkan jadi saya menggunakan jawaban yang diterima dan kemudian hanya melakukan komit baru.
Mark Edington
11
# Check out to a temporary branch:
git checkout --orphan TEMP_BRANCH

# Add all the files:
git add -A

# Commit the changes:
git commit -am "Initial commit"

# Delete the old branch:
git branch -D master

# Rename the temporary branch to master:
git branch -m master

# Finally, force update to our repository:
git push -f origin master
Megha Sahu
sumber
3
Bukan jawaban: Pertanyaannya adalah, "bagaimana menghapus komit pertama", dan bukan "bagaimana menghapus semua kecuali komit terakhir".
peterh
1
Saya mencari persis ini. Terima kasih!
Krzysztof Tomaszewski
6

Anda mungkin hanya ingin mengedit komit pertama Anda (karena selalu ada komit pertama di git repo). Pertimbangkan untuk menggunakan git commit --amend --reset-authordaripada yang biasa git commit --amend.

Max Beikirch
sumber
1
Bukan jawaban: pertanyaannya ingin menghapus komit pertama, dan tidak mengubah properti yang terakhir.
peterh
@ peterh-ReinstateMonica Untuk klarifikasi: Komit dapat diubah selama rebase interaktif untuk mengubah konten mereka sepenuhnya, tetapi --reset-penulis perlu disediakan untuk mengubah penulis juga. Dengan itu, Anda dapat sepenuhnya mengganti komit pertama yang Anda sukai. Lihat juga jawaban CharlesB.
Max Beikirch
3

Saya sedang mencari cara untuk membatalkan semua git melakukan dari repo, seolah-olah itu tidak pernah terjadi.

Rebasing akan bekerja hingga titik tertentu. Namun, yang pertama (kronologis git commit tertua) akan selalu bermasalah, karena tidak memiliki orangtua, sehingga akan salah.

Tidak satu pun dari jawaban ini yang cukup memecahkannya untuk saya. Tetapi setelah banyak pencarian dan coba-coba, saya menemukan ini berfungsi!

git update-ref -d HEAD
git push origin master -f

Semoga ini bisa membantu Anda. Semoga hari mu menyenangkan.

kp123
sumber
1
Agar jelas bagi siapa saja yang membaca jawaban ini: ini menghapus setiap komit, tetapi OP hanya ingin menghapus komit pertama yang dibuat untuk repo; jangan jalankan ini untuk menghapus komit pertama karena akan menghapus SEMUA komit.
Jody Bruchon
2

Cara lain yang dapat Anda lakukan adalah:

  1. Checkout ke cabang yang ingin Anda pertahankan (misalkan dev) git checkout dev
  2. Sekarang, hapus cabang yang ingin Anda atur ulang git branch -D master
  3. Sekarang, buat cabang kosong dengan nama yang sama git checkout --orphan master

Tentu saja, semua ini tergantung pada penggunaan Anda, tetapi jika Anda memiliki lebih dari satu cabang, menghapus .gitdirektori tidak masuk akal.

kumarharsh
sumber
3
Setelah melakukan ini, Anda harus menghapus cabang di remote sebelum mendorong. Kalau tidak, ketika mencoba mendorong Anda akan memiliki kesalahan ini:! [ditolak] master -> master (non-fast-forward) - error: gagal mendorong beberapa referensi ke '[email protected]: r1 / r2.git' - hint: Pembaruan ditolak karena ujung cabang Anda saat ini adalah di belakang - petunjuk: rekannya yang jauh. Integrasikan perubahan jarak jauh (mis. Petunjuk: 'git pull ...') sebelum mendorong lagi ... - Jika Anda melakukan git pull, semua komit kembali.
dxvargas
2

Jika Anda ingin menyimpan cabang lain, tetapi misalnya membuat mastercabang mulai baru tanpa riwayat umum ke cabang lain, salah satu cara aman untuk mencapai ini adalah dengan membuat repositori baru, dan mendorong konten yang ada di yang lama:

cd ..
git init newrepo
cd newrepo
# make some initial commits
git push ../oldrepo master:newmaster

Ini menciptakan newmastercabang di repositori lama, dengan sejarah yang tidak umum dengan cabang lainnya. Tentu saja, Anda bisa menimpanya masterjuga dengangit push -f .

Jika Anda ingin menghancurkan semua cabang dan semua konten yang ada, maka jalankan saja

rm -rf .git/
pengguna1338062
sumber
1
Bukan jawaban: OP ingin menghapus komit pertama, dan tidak memulai repo git baru dengan pohon kerja saat ini sebagai komit awal.
peterh
@peterh Saya setuju git rebase --rootmungkin apa yang diinginkan OP, tetapi mengingat jawaban ini memiliki dua upvotes, saya akan menahan diri untuk tidak menghapusnya jika seseorang masih menganggapnya relevan.
user1338062
Saya pikir jawaban ini adalah persis relevan - jika Anda ingin menghapus pertama komit dalam beberapa cabang, dan ada yang hanya satu komit! (Tetapi Anda juga ingin mempertahankan komitmen lain di cabang lain; dan Anda juga ingin melakukan ini agar perubahan berakhir di Bitbucket atau Github, bukan hanya secara lokal.) Saya percaya jawaban ini adalah salah satu cara untuk melakukan ini, dan Saya pikir ini mungkin satu-satunya cara di sini untuk melakukan ini. (Itu karena - juga sejauh yang saya bisa lihat - tidak ada cara untuk memaksa mendorong cabang lokal tanpa melakukan komitmen pada cabang terpencil dengan beberapa komit.)
MikeBeaton
0

Jika Anda baru saja melakukannya tetapi tidak mendorongnya maka hapus saja direktori .git dan git initlagi ...

Ali Sajid
sumber
@ Peterh Ya itu. Anda berasumsi (saya pikir) bahwa pertanyaan OP adalah tentang ingin menghapus komit pertama tetapi tetap melakukan komit selanjutnya. Kemungkinan lain (yang saya pikir cocok dengan pertanyaan OP dengan sangat baik - dan jawaban ini merupakan jawaban) ingin menghapus komit pertama dan hanya dari cabang, mengembalikannya kembali menjadi benar-benar kosong lagi.
MikeBeaton
@ MikeBeaton Anda benar. Saya menghapus komentar saya, tetapi kemudian saya harus memilih untuk menutup pertanyaan sebagai tidak jelas. Catatan, meskipun hanya saya yang membuat komentar ini, tetapi di belakang saya ada 40000 pengunjung, dan sebagian besar dari mereka menemukan pertanyaan ini dengan google - dan mereka tidak mendapatkan apa yang mereka inginkan.
peterh
Itu tampak ekstrem. Hapus pertanyaan? Mungkinkah (dengan sangat baik) berpendapat bahwa jawaban penuh untuk pertanyaan yang masuk akal adalah bahwa ada dua pendekatan berbeda yang perlu diambil, tergantung pada apakah ... dll? (Maksudku, aku, untuk satu, akan ingin tahu bagaimana untuk menghapus pertama komit ketika itu bukan satu-satunya komit, dan juga cara menghapus pertama komit ketika adalah satu-satunya komit. Ini tentu tidak jelas, dan tentu saja bergantung pada implementasi rincian spesifik, bahwa ternyata ternyata diperlukan pendekatan yang agak berbeda dalam setiap kasus.)
MikeBeaton
0

Jawaban atas pertanyaan tergantung pada apakah:

  • Anda ingin menghapus komit pertama DAN HANYA pada cabang (sementara meninggalkan cabang lain seperti sebelumnya), atau apakah

  • Anda ingin menghapus komit pertama pada beberapa cabang, sementara 'meninggalkan di tempat' komit berikutnya (dan cabang lainnya).

Yang kedua ini relatif lebih sederhana. Anda pada dasarnya harus mengulang ke root - sebagian besar jawaban di sini adalah tentang cara untuk melakukan ini.

Melakukan yang kedua (menghapus komit pertama dan hanya dari cabang sementara meninggalkan cabang lain sendirian) lebih sulit. Atau, paling tidak, terutama lebih sulit jika Anda menginginkannya terjadi dan agar perubahan tercermin kembali di GitHub atau Bitbucket. Tidak ada (sejauh yang saya tahu) di Git untuk mendorong atau memaksa mendorong cabang tanpa komitmen. Dan ada juga (sekali lagi, sejauh yang saya bisa lihat) tidak ada cara sama sekali untuk membuat cabang baru yang kosong tanpa komitmen di dalamnya baik di GitHub atau Bitbucket. Jadi Anda pada dasarnya harus membuat repositori baru untuk membuat cabang yang benar-benar kosong, dan kemudian menambahkan kembali cabang yang Anda inginkan (termasuk komit yang Anda inginkan) - sesuai jawaban @ user1338062.

Jadi saya harap jawaban ini mengklarifikasi apa yang mungkin tidak jelas - bahwa ada dua pendekatan berbeda yang perlu diambil, untuk dua skenario yang berbeda (lebih atau kurang masuk akal) yang merupakan dua hal yang Anda mungkin ingin dapat lakukan, dalam rangka untuk sepenuhnya menguasai melakukan apa yang diminta OP.

MikeBeaton
sumber