Gibt es eine Möglichkeit, das Speichern in Vim bis zum Festschreiben in Git zu verknüpfen?


11

Ich bin neu in der Welt von Vim und möchte es so gestalten, dass jedes Mal, wenn ich eine Datei speichere, diese zur Versionskontrolle verpflichtet wird. Ist das möglich?

Antworten:


4

Sie können die automatischen Befehle von Vim verwenden:

:autocmd BufWritePost * execute '!git add % && git commit -m %'

Das ist nicht getestet, aber es sollte die Datei hinzufügen und mit dem Dateinamen als Festschreibungsnachricht festschreiben.
Sie möchten BufWritePost, da dies nach dem Schreiben der Datei ausgelöst wird. Ich würde mir vorstellen, dass es viele lästige oder unsichere Randfälle gibt.


4

Ich verwende einen vim-Autobefehl, den ich in meine .vimrc einfüge. Der Befehl führt zunächst eine grobe Überprüfung durch, ob wir in einem Git-Verzeichnis arbeiten (indem er das Vorhandensein eines Git-Verzeichnisses entweder im aktuellen Verzeichnis oder mithilfe von überprüft git rev-parse), und verwendet dann git -a -m %, dass nur zuvor hinzugefügte Dateien bereitgestellt und festgeschrieben werden .

autocmd BufWritePost * execute '! if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m %; fi'

1
Am Ende des cmd, direkt nach fi, fehlt ein einfaches Anführungszeichen.
Andrew-Dufresne

2
Diese Version funktioniert nur, wenn Sie sich im Stammverzeichnis Ihres Repos befinden. Eine bessere Lösung ist autocmd BufWritePost * execute '! if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m %; fi', aus einer SO-Antwort
Andrew-Dufresne

Das funktioniert bei mir unter Linux. Irgendeine Idee, wie es unter Windows funktioniert?
user334287

2

Vielleicht möchten Sie sich das flüchtige Plugin ansehen , es ist ein sehr leistungsfähiges Git-Plugin für vim. Sie können auch ein autocmdwie vorgeschlagen donothingsuccessfullyeinrichten, aber es wird angezeigt :Gcommitoder :Gstatus(aus dem Sie Änderungen auswählen können, um sie dem Git-Index hinzuzufügen)


1

Aufbauend auf den Antworten, die andere gegeben haben:

autocmd BufWritePost * execute ':silent ! if git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m "Auto-commit: saved %"; fi > /dev/null 2>&1'

Dies ist völlig transparent. Sie erhalten nicht die Meldung "Drücken Sie die Eingabetaste, um fortzufahren" (aber wenn das Festschreiben nicht funktioniert hat, wissen Sie nicht, dass es fehlgeschlagen ist).


0

Sie könnten dies sicherlich mit einem Makro oder mit Befehl neu zuordnen.

(Überprüfen Sie /programming/117150/can-i-re-map-commands-in-vim )

Ich bin mir nicht sicher, ob es eine gute Option ist. Ich beherrsche Git momentan nicht und ich weiß, dass es manchmal anders ist als SVN. Aber ich würde dieses Auto-Commit nicht mit svn machen. Commit muss sinnvoll sein und darf nicht regelmäßig gespeichert werden.

Normalerweise schreiben Sie fest, weil Sie eine Funktion hinzugefügt, einen Fehler behoben haben, ... nicht nur, weil Sie an einer Datei gearbeitet haben. Sie werden nicht mit einem nicht kompilierten Projekt oder einer nicht abgeschlossenen Funktion enden.


Das stimmt, aber ich möchte auch ein Übernacht-Skript haben, das Dateien, die erfolgreich kompiliert wurden, vom Repo "Save-on-Commit" in ein Repo "Sinnvolle Änderung" verschiebt.
gonzo.floyd

Nun, mit Git ist das keine schlechte Idee. "Häufig verpflichten" ist eine Art Motto. Dies funktioniert auch auf diese Weise besser, da Sie mit mehreren Entwicklern und minimalen Problemen gleichzeitig an derselben Datei arbeiten können. Es wäre sehr nützlich, sich in den Speichermechanismus von vim einzuklinken.
Metagrapher

Workflows in Git können sich grundlegend von Subversion unterscheiden. Sie werden dies vielleicht nie in svn tun, weil es missbräuchlich wäre, aber es hat vollkommen gültige Verwendungen in git. Beispielsweise könnte ein Testintegrationsserver an einen Testzweig angeschlossen werden. Das automatische Festschreiben beim Speichern wird dann sehr nützlich. Wenn Sie an dem Punkt angelangt sind, an dem etwas funktioniert, verwenden Sie git rebase, um alle Aktivitäten zu einem einzigen Commit mit einer aussagekräftigen Nachricht zusammenzufassen und dann in Ihren Entwicklungszweig zu integrieren. Wenn dies beängstigend oder komplex klingt, liegt dies nur daran, dass Sie an die Einschränkungen eines nicht verteilten Quell-VCS angepasst sind.
Caleb

0

Ich weiß, dass diese Frage alt ist und dies eine offensichtliche Eigenwerbung ist, aber ich habe ein Vim-Plugin geschrieben, das bestimmte Shell-Skripte auslöst, die nach bestimmten Vim- autocmdEreignissen ausgeführt werden. Beispielsweise wird ein Skript mit dem Namen .bufwritepost.vimhook.shjedes Mal (synchron) ausgeführt, wenn der BufWritePostBefehl ausgelöst wird. Sie können dann problemlos die gewünschte Logik für die Ausführung des Git-Commits in dieses Skript aufnehmen. Das Plugin setzt bestimmte Namenskonventionen dieser Skripte voraus und unterstützt auch "Hook" -Skripte, die nur für Dateien ausgelöst werden, die bestimmten Namen entsprechen oder bestimmte Erweiterungen haben.

Ausführliche Informationen: https://github.com/ahw/vim-hooks


0

Ich möchte meine Meinung zu diesem Problem melden.

Ich habe das vimrc.vimin einem Git-Repository ( $VIMCONFmit einem Bootstrap .vimrc) und zugeordnet <Leader>ve("vim edit"), um das vimrc in einem neuen Tab zu öffnen. Dies hat keine Auswirkungen auf das aktuelle Arbeitsverzeichnis.

Wenn ich also vimrc.vimvon einem vim bearbeite, das in einem anderen Verzeichnis außerhalb meines vim git-Repositorys gestartet wurde, schlägt der von Nick Edwards diskutierte Ansatz fehl. Mein Hack ist der folgende (für Windows und Linux)

if has('win32')
    " The git command has to be passed to git. So we need to call bash.exe.
    autocmd BufEnter *vimrc.vim silent! lcd %:p:h
    autocmd BufWritePost *vimrc.vim if expand('<amatch>') =~ substitute(expand('$VIMCONF\vimrc.vim'), '\', '/', "g") | execute '! git add % & git commit -m %' | endif
else " Linux
    autocmd BufWritePost *vimrc.vim
        \ if expand('<amatch>') =~ expand($VIMCONF)."/vimrc.vim" |
        \ let tempdir = getcwd() | execute 'cd' fnameescape(expand('<amatch>:h')) | 
        \ execute '! if git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m % ; fi' |
        \ execute 'cd' fnameescape(tempdir) |
        \ endif
endif

Erläuterung:

  1. Für Windows ändere ich das Verzeichnis in den Speicherort der vimrc-Datei. Dies ist nicht das Beste, und ich könnte später ändern, um Linux ähnlich zu sein. Nehmen Sie das nicht zu ernst, aber Sie möchten es vielleicht als Leitfaden verwenden. githat auf dem Weg sein (dh sollten Sie in der Lage sein , geben git <ENTER>in cmd.exe)
  2. Für Linux überprüfe ich zuerst, ob ich die richtige vimrc.vim bearbeite
  3. Speichern Sie das aktuelle Arbeitsverzeichnis in tempdir
  4. Wechseln Sie in die Datei vimrc.vim
  5. Mach das Git Commit
  6. Kehren Sie zum vorherigen Arbeitsverzeichnis zurück
  7. Ich drücke die Git-Änderungen manuell

Anmerkungen:

  1. Befehle können in vim mit "verkettet" werden |. Die Kette wird abgebrochen, wenn einer der Befehle fehlschlägt. Um mehrere Zeilen zu durchbrechen, beginnen Sie die nächste Zeile mit \.
  2. Dies kann auf ftplugin-Dateien erweitert werden. Ihre Filter werden *.vimund seinexpand($VIMCONF)."/ftplugin/"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.