2012-01-26 7 views
10

mojego obecnego git status wygląda następująco:Git częściowe popełniają inscenizowanych zmiany

# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
#  modified: docs/file3.org 
#  modified: src/main/R/lib.R 
# 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
#  modified: docs/file3.org 
#  modified: src/main/R/lib.R 

które chciałbym popełnić wystawił zmiany docs/file3.org pierwsze, potem drugie etapowe zmiany. Ale jeśli wykonam git commit -m '...' docs/file3.org, spowoduje to przeniesienie do tego pliku nieplanowanych zmian &.

Czy istnieje prosty sposób na zrobienie tego? Czy muszę stash moje zmiany niezarządzane, unstage jeden z plików, popełnić drugi, restage, commit i stash pop?

+2

Możliwe, że zachowanie 'git commit' zmieniło się od czasu opublikowania tego pytania, ale od grudnia 2015 r. Polecenie, które próbowałeś (określając ścieżki, które chcesz zatwierdzić) powinno działać. Z [documentation] (https://git-scm.com/docs/git-commit) opcji git commit - onlyly: * Dokonaj commit pobierając zaktualizowaną zawartość drzewa roboczego ścieżek określonych w komendzie linii, bez względu na zawartość, która została wystawiona na inne ścieżki. Jest to domyślny tryb działania git commit, jeśli w wierszu poleceń podano dowolną ścieżkę, w którym to przypadku tę opcję można pominąć. * – waldyrious

+0

Naprawdę oczekiwałbym, że 'git commit' (bez określonych ścieżek) będzie zatwierdzać * tylko wystawiony * modyfikacje. W każdym razie, inną opcją jest użycie 'git gui' dla operacji na scenie i zatwierdzeniu. – aweibell

Odpowiedz

9

Ponieważ wystarczy popełnić pomostowe zmiany w pliku, można po prostu ukryta, zachowując indeksowanych zmian w stanie nienaruszonym, a popełnienie plik po tym.

git stash --keep-index #Note that the staged changes also become part of the stash 
git commit -m "Commit only one file" docs/file3.org 

git commit -m "Commit other staged changed" 
git stash pop 
# This may raise CONFLICTS since the stash includes the earlier staged changes. 
# In case of conflict, the stash is not popped, so you need to drop it explicitly. 
+1

To jest zasadniczo przepływ, który opisałem w moim pytaniu, które miałem nadzieję * nie * zrobić. =) Ale jeśli to jest to, co mamy, to jest to, co mamy, dzięki. –

+0

Nie do końca rozumiem, że jest to możliwe, jeśli nie możesz podzielić commit tak czy inaczej? Używanie git stash naprawdę brzmi jak obejście. – aweibell

1

git stash to najlepsza opcja w połączeniu z.

git add --interactive 

Powinno to umożliwić "przywrócenie" (poza sceną) niektórych plików już dodanych do indeksu.
Następnie git stash pozwoliłoby na zapisanie tych plików i ich przywrócenie.

(Patrz "git add --patch and --interactive" artykuł dla przykładu)

2

mam zamiar założyć, że jesteś na master za to wszystko ...

git branch whatever 
git commit # commit currently staged changes as 'commit1' 
git add docs/file3.org 
git commit # commit unstaged changes as 'commit2' 

Będziesz teraz mieć ten

master 
    \ 
    \--commit1--commit2 

Teraz uruchom git log i zarejestruj SHA dla "commit1" i "commit2".

git checkout master 
git cherry-pick commit2SHA 
git cherry-pick commit1SHA 

Który daje

master--newcommit2--newcommit1 
    \ 
    \--commit1--commit2 

a następnie można zniszczyć 'Cokolwiek' oddział

git branch -D whatever 

zmienił:

Y ou może również zrobić coś podobnego przy użyciu zapas:

git stash --keep-index # Save unstaged changes 
git stash    # Save staged changes 
git stash pop [email protected]{1} # Pop unstanged changes 
git commit ...   # Commit unstanged changes 
git stash pop [email protected]{0} # Pop staged changes 
git commit ...   # Commit staged changes 
+1

W twoim pierwszym 'git commit', czy to nie spowoduje, że oba pliki są obecnie przemieszczane? Właśnie tego staram się uniknąć, chcę jednego zestawu porcji z jednego pliku w moim pierwszym zatwierdzeniu. –