2014-04-19 8 views
6

Ich bin auf der Suche nach Hilfe, bitte benutze Emacs/Magit, um die lokalen Repository-Änderungen auf die Remote-Website und Github auf einen Schlag zu übertragen.Emacs - Wie man ein Git-Repository auf mehrere Fernbedienungen pusht

Ich fand einen nicht-Emacs/nicht-Magit verwandten Thread (https://stackoverflow.com/a/3195446/2112489), mit Kommentaren, dass es die definitive Antwort auf das Drücken auf eine Fernbedienung und Github ist, und es hat ein paar hundert Daumen hoch. Ich nehme an (vielleicht falsch), das ist ein guter Ausgangspunkt für die lokale.gitconfig Datei im Verzeichnis $HOME auf meinem Computer.

[remote "GitHub"] 
    url = [email protected]:elliottcable/Paws.o.git 
    fetch = +refs/heads/*:refs/remotes/GitHub/* 
[branch "Master"] 
    remote = GitHub 
    merge = refs/heads/Master 
[remote "Codaset"] 
    url = [email protected]:elliottcable/paws-o.git 
    fetch = +refs/heads/*:refs/remotes/Codaset/* 
[remote "Paws"] 
    url = [email protected]:Paws/Paws.o.git 
    fetch = +refs/heads/*:refs/remotes/Paws/* 

Der grundlegende Befehl Push-in Emacs/Magit schiebt nur einer nach dem anderen:

C-u P P [and then use arrow keys to select from the choices in the minibuffer] RET 

Siehe Magit Spickzettel der verfügbaren Befehle: http://daemianmack.com/magit-cheatsheet.html


Vorläufiger Denken - Verwenden Sie /usr/local/git/bin/git remote -v, um eine Liste der bereits konfigurierten Fernbedienungen zu erhalten d Verwenden Sie dann die Ergebnisse, um zu jedem einzelnen zu gelangen. . . machbar, aber komplex.

$ MP:my_project.git HOME$ /usr/local/git/bin/git remote -v 

    origin [email protected]:lawlist/my_project.git (fetch) 
    origin [email protected]:lawlist/my_project.git (push) 
    remote_website [email protected]:my_project.git (fetch) 
    remote_website [email protected]:my_project.git (push) 

COMMAND-LINE RECIPE - separat an die Fern schieben und zu Github:

;; Setup the remote repository and the hook; and the remote destination folder. 
ssh [email protected] 
mkdir /home/lawlist/my_project.git 
cd my_project.git 
git init --bare 
;; git update-server-info # If planning to serve via HTTP 
cat > /home/lawlist/my_project.git/hooks/post-receive ;; RET 
#!/bin/sh ;; RET 
GIT_WORK_TREE=/home/lawlist/my_project git checkout -f ;; RET 
;; C-d 
chmod 755 /home/lawlist/my_project.git/hooks/post-receive 
mkdir /home/lawlist/my_project 
exit 

;; On local machine. 
mkdir /Users/HOME/.0.data/.0.emacs/elpa/my_project.git 
touch /Users/HOME/.0.data/.0.emacs/elpa/my_project.git/README.md 
cd /Users/HOME/.0.data/.0.emacs/elpa/my_project.git 
/usr/local/git/bin/git init 
/usr/local/git/bin/git add . 
/usr/local/git/bin/git commit -m "First commit." 
curl -u lawlist:12345678 https://api.github.com/user/repos -d '{"name":"my_project.git"}' 
/usr/local/git/bin/git remote add origin [email protected]:lawlist/my_project.git 
/usr/local/git/bin/git remote add remote_website [email protected]:my_project.git 
/usr/local/git/bin/git push origin master 
/usr/local/git/bin/git push remote_website master 

;; For modification of local files 
/usr/local/git/bin/git add . 
/usr/local/git/bin/git commit -m "This is a modification . . . ." 
/usr/local/git/bin/git push origin master 
/usr/local/git/bin/git push remote_website master 
+1

+1 Danke für das Teilen! – itsjeyd

Antwort

4

EDIT (23. April 2014): Added eine nicht-Magit Lösung um alles zu staffeln, alles zu übertragen (mit einer Standard-Commit-Nachricht) und an alle Fernbedienungen zu drücken.

EDIT (24. April 2014): Die gedruckte Ausgabe aller Prozesse wird nun auf die git-status-buffer gesendet, die am Ende der Funktion angezeigt wird - mit Optionen für den Benutzer zu wählen, was mit dem zu tun, Fenster - zB Fenster löschen, Puffer und Fenster löschen oder nichts tun. Einige schöne Farben mit (propertize "[...]" 'face 'font-lock-warning-face) hinzugefügt. Der erste Entwurf der Funktion, der auf einer bereits vorhandenen Installation von Magit beruht, wurde auf den Grund dieser Antwort verschoben - diese Funktion funktioniert, ist aber nicht so ausgefeilt wie die aktuelle Version, die nicht auf einer Installation von Magit beruht.

(defvar git-status-buffer "*GIT-STATUS*" 
    "The buffer name of the git-status-buffer.") 

(defvar git-branch-name nil 
"The current branch of the working Git directory.") 
(make-variable-buffer-local 'git-branch-name) 

(defvar git-remote-list nil 
"List of remote locations -- e.g., lawlist_remote or github_remote.") 
(make-variable-buffer-local 'git-remote-list) 

(defvar git-commit-message (format "Committed -- %s" (current-time-string)) 
"The predetermined Git commit message.") 
(make-variable-buffer-local 'git-commit-message) 

(defun git-branch-process-filter (proc string) 
    (with-current-buffer (get-buffer git-status-buffer) 
    (set (make-local-variable 'git-branch-name) 
     (car (split-string string "\n"))))) 

(defun git-push-process-filter (proc string) 
    (when (string-match "password" string) 
    (process-send-string 
     proc 
     (concat (read-passwd "Password: ") "\n"))) 
    (when (and 
     (not (string-equal "Password: " string)) 
     (not (string-equal "\n" string)) 
     (not (string-equal "stdin: is not a tty\n" string))) 
    (with-current-buffer git-status-buffer 
     (goto-char (point-max)) 
     (insert "\n" (replace-regexp-in-string "\^M" "\n" string))))) 

(defun git-push-process-sentinel (proc string) 
    (when (= 0 (process-exit-status proc)) 
    (with-current-buffer (get-buffer git-status-buffer) 
     (insert 
     "\n" 
     (propertize 
      (format "Process `%s` has finished pushing to `%s`." proc git-remote-name) 
      'face 'font-lock-warning-face) 
     "\n")) 
    (throw 'exit nil))) 

(defun stage-commit-push-all() 
"This function does the following: 
    * Save the current working buffer if it has been modified. 
    * Obtain the name of the selected branch in the current working buffer. 
    * Gather a list of all remotes associated with working directory Git project. 
    * Stage all -- `/usr/local/git/bin/git add .` 
    * Commit all -- `/usr/local/git/bin/git commit -m [git-commit-message]` 
    * Push to all remotes: `/usr/local/git/bin/git push -v [remote] [current-branch]`" 
(interactive) 
    (when (buffer-modified-p) 
    (save-buffer)) 
    (when (get-buffer git-status-buffer) 
    (with-current-buffer (get-buffer git-status-buffer) 
     (kill-local-variable 'git-remote-list) 
     (kill-local-variable 'git-branch-name) 
     (erase-buffer))) 
    (start-process 
    "current-branch" 
    git-status-buffer 
    "/usr/local/git/bin/git" 
    "rev-parse" 
    "--abbrev-ref" 
    "HEAD") 
    (set-process-filter (get-process "current-branch") 'git-branch-process-filter) 
    (set-process-sentinel 
    (get-process "current-branch") 
    (lambda (p e) (when (= 0 (process-exit-status p)) 
     (set-process-sentinel 
     (start-process 
      "list-remotes" 
      git-status-buffer 
      "/usr/local/git/bin/git" 
      "remote" 
      "-v") 
     (lambda (p e) (when (= 0 (process-exit-status p)) 
      (let* (
       beg 
       end 
       git-remote-name) 
      (with-current-buffer (get-buffer git-status-buffer) 
       (goto-char (point-max)) 
       (while (re-search-backward "\(push\)" nil t) 
       (beginning-of-line 1) 
       (setq beg (point)) 
       (re-search-forward "\t" nil t) 
       (setq end (- (point) 1)) 
       (setq git-remote-name (buffer-substring-no-properties beg end)) 
       (setq git-remote-list 
        (append (cons git-remote-name git-remote-list)))))) 
      (set-process-sentinel 
      (start-process 
       "stage-all" 
       git-status-buffer 
       "/usr/local/git/bin/git" 
       "add" 
       ".") 
      (lambda (p e) (when (= 0 (process-exit-status p)) 
       (with-current-buffer (get-buffer git-status-buffer) 
       (goto-char (point-max)) 
       (insert "\n")) 
       (set-process-sentinel 
       (start-process 
        "commit-all" 
        git-status-buffer 
        "/usr/local/git/bin/git" 
        "commit" 
        "-m" 
        git-commit-message) 
       (lambda (p e) (when (= 0 (process-exit-status p)) 
        (mapcar (lambda (git-remote-name) 
        (let ((proc 
         (start-process 
          "push-process" 
          git-status-buffer 
          "/usr/local/git/bin/git" 
          "push" 
          "-v" 
          (format "%s" git-remote-name) 
          (format "%s" 
          (with-current-buffer (get-buffer git-status-buffer) 
           git-branch-name))))) 
         (set-process-filter proc 'git-push-process-filter) 
         (set-process-sentinel proc 'git-push-process-sentinel) 
         (recursive-edit))) 
        (with-current-buffer (get-buffer git-status-buffer) 
         git-remote-list)) 
        (display-buffer (get-buffer git-status-buffer)) 
        (message (concat 
        git-status-buffer 
        " -- [" 
        (propertize "d" 'face 'font-lock-warning-face) 
        "]elete window | [" 
        (propertize "k" 'face 'font-lock-warning-face) 
        "]ill buffer + delete window | [" 
        (propertize "n" 'face 'font-lock-warning-face) 
        "]othing")) 
        (let* (
         (git-window-options (read-char-exclusive)) 
         (target-window (get-buffer-window git-status-buffer))) 
        (cond 
         ((eq git-window-options ?d) 
         (with-current-buffer (get-buffer git-status-buffer) 
          (delete-window target-window))) 
         ((eq git-window-options ?k) 
         (with-current-buffer (get-buffer git-status-buffer) 
          (delete-window target-window) 
          (kill-buffer (get-buffer git-status-buffer)))) 
         ((eq git-window-options ?n) 
         (message "Done!")) 
         (t (message "You have exited the sub-function.")))) 
       ))))))))))))) 

erster Entwurf (19. April 2014): Für diese Funktion eine bereits bestehende Installation von Magit. Der Code über does nicht erfordern Installation von Magit.

(defun push-to-all-remotes() 
"This function requires a pre-existing installation of Magit, and the function assumes 
that the user has already staged and committed -- i.e., it only pushes to all remotes." 
(interactive) 
    (let* (beg end remote) 
    (when (get-buffer "*REMOTES*") 
     (with-current-buffer (get-buffer "*REMOTES*") 
     (erase-buffer))) 
    (set-process-sentinel 
     (start-process 
     "list-remotes" 
     "*REMOTES*" 
     "/usr/local/git/bin/git" 
     "remote" 
     "-v") 
     (lambda (p e) (when (= 0 (process-exit-status p)) 
     (with-current-buffer (get-buffer "*REMOTES*") 
      (goto-char (point-max)) 
      (while (re-search-backward "\(push\)" nil t) 
      (beginning-of-line 1) 
      (setq beg (point)) 
      (re-search-forward "\t" nil t) 
      (setq end (- (point) 1)) 
      (setq remote (buffer-substring-no-properties beg end)) 
      (magit-run-git-async 
       "push" 
       "-v" 
       remote 
       (magit-get-current-branch))))))) 
    (display-buffer (get-buffer magit-process-buffer-name)))) 
Verwandte Themen