Cập nhật
Tôi đã tạo một bí danh git squash-all
.
Ví dụ sử dụng : git squash-all "a brand new start"
.
[alias]
squash-all = "!f(){ git reset $(git commit-tree HEAD^{tree} -m \"${1:-A new start}\");};f"
Hãy cẩn thận : nhớ cung cấp một nhận xét, nếu không, thông báo cam kết mặc định "Một khởi đầu mới" sẽ được sử dụng.
Hoặc bạn có thể tạo bí danh bằng lệnh sau:
git config --global alias.squash-all '!f(){ git reset $(git commit-tree HEAD^{tree} -m "${1:-A new start}");};f'
Lót
git reset $(git commit-tree HEAD^{tree} -m "A new start")
Lưu ý : ở đây " A new start
" chỉ là một ví dụ, vui lòng sử dụng ngôn ngữ của riêng bạn.
TL; DR
Không cần phải ép, sử dụng git commit-tree
để tạo một cam kết mồ côi và đi với nó.
Giải thích
tạo một cam kết thông qua git commit-tree
Cái gì git commit-tree HEAD^{tree} -m "A new start"
là:
Tạo một đối tượng cam kết mới dựa trên đối tượng cây được cung cấp và phát ra id đối tượng cam kết mới trên thiết bị xuất chuẩn. Thông điệp tường trình được đọc từ đầu vào tiêu chuẩn, trừ khi các tùy chọn -m hoặc -F được đưa ra.
Biểu thức HEAD^{tree}
có nghĩa là đối tượng cây tương ứng với HEAD
, cụ thể là đầu của nhánh hiện tại của bạn. xem Cây-Đối tượng và Cam kết-Đối tượng .
đặt lại nhánh hiện tại về cam kết mới
Sau đó, git reset
chỉ cần đặt lại nhánh hiện tại thành đối tượng cam kết mới được tạo.
Bằng cách này, không có gì trong không gian làm việc được chạm vào, cũng không cần rebase / squash, điều này làm cho nó thực sự nhanh. Và thời gian cần thiết không liên quan đến kích thước kho lưu trữ hoặc độ sâu lịch sử.
Biến thể: Repo mới từ mẫu dự án
Điều này rất hữu ích để tạo "cam kết ban đầu" trong một dự án mới bằng cách sử dụng một kho lưu trữ khác làm mẫu / archetype / seed / skeleton. Ví dụ:
cd my-new-project
git init
git fetch --depth=1 -n https://github.com/toolbear/panda.git
git reset --hard $(git commit-tree FETCH_HEAD^{tree} -m "initial commit")
Điều này tránh việc thêm repo mẫu dưới dạng từ xa ( origin
hoặc nếu không) và thu gọn lịch sử của repo mẫu vào cam kết ban đầu của bạn.