我正在寻找一些帮助,请使用Emacs/Magit将本地存储库更改推送到远程网站和Github,一口气。

我发现了一个与Emacs/非Magit不相关的线程(https://stackoverflow.com/a/3195446/2112489),并有评论指出,这是将其推向 Remote 和Github的最终答案,并且它有数百个赞誉。我假设(也许是错误地)这是计算机上.gitconfig目录中本地$HOME文件的一个很好的起点。

[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/*

Emacs/Magit中的基本Push命令一次只能推送一次:
C-u P P [and then use arrow keys to select from the choices in the minibuffer] RET

请参阅可用命令的Magit速查表:http://daemianmack.com/magit-cheatsheet.html

初步思考-使用/usr/local/git/bin/git remote -v获取已配置的远程服务器列表,然后使用结果推送到每个列表。 。 。可行,但复杂。
$ 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 -分别推送到远程和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

最佳答案

EDIT (2014年4月23日):添加了非Magit解决方案来暂存所有,提交所有内容(带有默认的提交消息)并推送到所有 Remote 。

EDIT (2014年4月24日):``所有进程的打印输出现在都发送到git-status-buffer,它显示在功能的末尾-带有供用户选择对窗口进行操作的选项-例如,删除窗口,删除缓冲区和窗口,或者什么也不做。使用(propertize "[...]" 'face 'font-lock-warning-face)添加了一些漂亮的颜色。依赖于先前安装的Magit的功能的初稿已移至该答案的底部-该功能有效,但不如不依赖Magit的当前版本复杂。

(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.")) ))
                )))))))))))))

初稿(2014年4月19日):此功能需要预先安装Magit。 上方所示的代码不需要安装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)) ))

关于Emacs-如何将Git存储库推送到多个远程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23176957/

10-13 00:51