【问题标题】:How do I avoid typing "git" at the begining of every Git command?如何避免在每个 Git 命令的开头输入“git”?
【发布时间】:2019-10-23 14:11:48
【问题描述】:

我想知道是否有办法避免在每个 Git 命令的开头输入单词 git

如果有一种方法可以在打开命令提示符进入“Git 模式”之后,在开头只使用一次git 命令,那就太好了。

例如:

git>

在此之后,我们键入的每个命令默认都被解释为 Git 命令。

类似于我们使用 MySQL shell 编写数据库命令的方式:

mysql>

这将使我不必每天输入数百次git

注意:我在 Windows 上使用 git-bash

【问题讨论】:

  • 对于那些因离题而投票结束的人,请阅读您点击的文本:“关于通用计算硬件和软件的问题对于 Stack Overflow 来说是离题 除非它们直接涉及主要用于编程的工具。”。 Git是程序员使用的工具。事实证明,它在这个网站上有自己的标签。
  • 你为什么要输入这么多“git”?您的 IDE 应该具有强大的 vcs 集成功能,只需按键即可使用。你宁愿每天输入 50 次“git pull”,还是按 ctrl-t... 停止 成为命令行战士,当你不需要时 ;)
  • @vikingsteve 实际上所有 git 帮助和智慧都是通过命令行给出的。
  • @vikingsteve 我输入了很多,因为它更快。我输入 ~100wpm,如果我像使用 Git 一样熟悉按键,则输入更多;与单击 GUI 相比,它更容易。您最喜欢的 IDE 可能有键盘快捷键。这对你很好。当 git blah 已经在我的肌肉记忆中时,为什么 会浪费时间学习它们?
  • 应该有一个“这个问题应该被关闭,因为用户提出了一个没有意义的问题”——就像我明白你在问什么,但是 shell 将如何认识你如果确实有办法做到这一点,想输入“非以 git 命令开头”。

标签: git version-control command-line-interface git-bash


【解决方案1】:

之后

while read -erp "*git*${PS1@P}" cmd rest; do 
        if _=`git help $cmd 2>&-`
                then eval git $cmd "$rest"
                else eval $cmd "$rest"
        fi
done

我们输入的每个命令默认解释为 Git 命令

如果它看起来像一个,否则它将被按原样解释,因此您可以将 git 与其他命令混合使用,如果您想使用双关命令,只需在其前面加上反斜杠,rm foo 将是 eval 'd 为git rm foo,但\rm foo 将运行普通的rm 命令。 ^d 像往常一样结束它。

【讨论】:

    【解决方案2】:

    从今天开始:GitHub CLI 可用。

    GitHub CLI 将 GitHub 带到您的终端。它减少了上下文 切换,帮助您集中注意力,并使您能够更轻松地编写脚本和 创建自己的工作流程。今年早些时候,我们宣布了 GitHub CLI。自从我们发布测试版以来,用户已经创建了超过 250,000 个拉取请求,执行超过 350,000 次合并,并创建超过 GitHub CLI 的 20,000 个问题。我们收到了这么多周到 反馈,今天 GitHub CLI 已经结束测试版,可供 在 Windows、macOS 和 Linux 上下载。

    【讨论】:

      【解决方案3】:

      使用方括号编辑器,代码和 git 命令易于使用,功能也很多。

      右上角第二个双目图标用于安装扩展。

      像上图一样搜索扩展brackets git并安装。

      再次回到右上角会显示第四个图标,所以只需单击并查看如上图所示的更改。

      如果要安装支架,请使用以下命令:

      sudo add-apt-repository ppa:webupd8team/brackets
      sudo apt-get update
      sudo apt-get install brackets
      

      更多信息,您可以阅读:How to Install Brackets Code Editor in Ubuntu and Linux MintUbuntupit

      【讨论】:

        【解决方案4】:

        当我将 Windows 7 与 Conemu 一起使用时,我将以下内容添加到我的开发环境启动脚本中:

        doskey g=git $*
        

        有了这个,我可以只使用g 命令而不是输入git。 上次我尝试使用 Windows 10 和 Conemu,它不起作用,我认为存在错误,但值得一试。

        【讨论】:

          【解决方案5】:

          对于基本的东西,你可以这样做:

          function ggit(){ while true; do printf 'git> '; read; eval git $REPLY; done }
          
          git> status
          On branch master
          Your branch is ahead of 'origin/master' by 1 commit.
            (use "git push" to publish your local commits)
          
          Changes not staged for commit:
            (use "git add/rm <file>..." to update what will be committed)
            (use "git checkout -- <file>..." to discard changes in working directory)
          
              deleted:    yarn.lock
          
          no changes added to commit (use "git add" and/or "git commit -a")
          git> add .
          git> status
          On branch master
          Your branch is ahead of 'origin/master' by 1 commit.
            (use "git push" to publish your local commits)
          
          Changes to be committed:
            (use "git reset HEAD <file>..." to unstage)
          
              deleted:    yarn.lock
          
          git>
          

          ctrl+c 退出

          【讨论】:

          • 不错的主意,但是有两个问题。一、;后面do导致bash: syntax error near unexpected token ;'`二、eval部分容易出现漏洞。例如,考虑一下如果我在这个小 shell 中输入 status;cat /etc/passwd 会发生什么。无害的示例,但您知道会发生什么。您可以将其简化为 while IFS= read -r -p "git&gt; " gitcmd; do [ "x$gitcmd" != "x" ] &amp;&amp; git "$gitcmd";done 这当然不是防弹的,但 1 - 它更简单,2 - 避免非 git 命令执行(通过双引号) .不理想,稍微好一点
          • @Abigail Funny :) 为什么是的,shell 本身并不是最安全的应用程序。即使catting a file 也可能是个问题。但是,我最初的意思是,我们看不到 mysql 解释器执行 shell 命令,至少在开头没有 system\!。假设这个“repl”只执行git 命令,实际上它允许的不止于此。
          • @Abigail 我不害怕,因为我知道这是做什么的。其他不这样做的人 - 最终可能会破坏他们不应该破坏的东西。再说一遍 - eval 不是运行命令的最佳主意,尤其是在涉及用户控制的输入时。
          • 修正了do之后的错字。谢谢!回复:安全性:这显然不意味着要作为一个单独的应用程序分发。如果您不喜欢输入 git,只需输入您的 .bash_profile。我不太担心它“不安全”。如果您在 bash 中粘贴您不理解的内容(包括这个 oneliner 脚本),那么您将度过一段糟糕的时光。我喜欢这个,因为它简单、易写易读,而且易于改进。
          【解决方案6】:

          我知道这是一个很晚的答案,但这个问题确实引起了我的注意,因为我已经处理这种重复很长一段时间了。

          我不确定你的情况,但老实说我 (我重复 DON'T)想为每个 git 命令创建别名,所以改为我写了一个名为NoGit的python脚本来解决这个问题:

          #!/usr/bin/env python
          import sys, os, signal, atexit, readline, subprocess
          
          commands, stop, history_file = [], False, os.path.join(os.getcwd(), "git.history")
          
          def run_commands():
            stop = True
            for cmd in commands:
              command = ["git" if not cmd.startswith("git ") else ""]
              command = [cmd] if command[0] == "" else [command[0], cmd]
              subprocess.Popen(command).communicate()
              commands = []
          
          def signal_handler(sig, frame):
            run_commands()
            sys.exit(0)
          
          try:
            readline.read_history_file(history_file)
            signal.signal(signal.SIGINT, signal_handler)
          
            while True:
              if stop == True:
                break
              command = input("git> ")
              if command == "%undo":
                commands.pop()
              elif command == "%run":
                run_commands()
              elif command == "%exit":
                sys.exit(0)
              else:
                commands += [cmd.strip() for cmd in command.split(";")]
          
            signal.pause()
            readline.set_history_length(-1)
          except IOError:
            pass
          
          atexit.register(readline.write_history_file, history_file)
          

          NoGit 是一个简单的python 脚本,用于防止“git”关键字的不必要重复。

          文档:

          • %undo 命令从堆栈中删除最后一个命令
          • %run 命令运行堆栈中的命令并清除堆栈
          • %exit 命令关闭 CLI 而不执行任何操作
          • ctr+c 与运行%run; %exit 相同
          • 脚本将执行的命令保存到与脚本位于同一文件夹中的名为 git.history 的文件中
          • 您可以使用分号在一行中添加多个命令
          • 您可以在命令的开头使用关键字git,脚本不会复制它(EG:git init不会变成git git init

          示例命令:

          1. init
          2. add .
          3. stage .
          4. commit -m "inital commit"
          5. %run; %exit

          附加信息(适用于 Linux 用户):

          如果您愿意,可以删除 .py 扩展名并将其转换为可执行文件,使用:

          mv ./git.py ./git
          chmod +x ./git
          

          那么不要像这样调用脚本:

          python3 git.py
          

          你应该运行它:

          ./git
          

          附加信息(针对懒人):

          如果您很懒惰并且不想输入 ./,那么您可以将此脚本移动到您的 /bin/ 文件夹并为其创建一个别名。

          如果您真的,真的很懒,请使用以下命令:

          sudo cp ./git /bin/nogit
          sudo chmod +x /bin/nogit
          alias nogit='/bin/nogit'
          

          如果您真的,真的,真的懒惰,请复制并粘贴以下一行:

          sudo cp ./git /bin/nogit && sudo chmod +x /bin/nogit && alias nogit='/bin/nogit'
          

          如果你的懒惰已经达到了人类以前不知道的水平,这里有一个更紧凑的版本:

          sudo cp ./git /bin/nogit;sudo chmod +x /bin/nogit;alias nogit='/bin/nogit'
          

          祝你好运。

          【讨论】:

            【解决方案7】:

            使用您的编辑器。

            从您喜欢的编辑器(如 vs code)中输入命令(如 commit),然后使用 git 提高效率:

            或输入git 获取所有命令:

            【讨论】:

            • 我对所有这些反对票感到惊讶。对于使用支持这些功能的 IDE 的人来说,这并不是一个糟糕的答案。
            • 我认为人们投了反对票,因为不是每个人都使用/喜欢 VS-Code。无论哪种方式,我认为这是一个不错的解决方案,所以我 +1。
            • @LogicalBranch,人们通常从命令行使用 git,我知道这一点,但是一些编辑器中的 git 支持存在,值得尝试。
            • 我不喜欢这个答案,因为不是每个人都使用 VS 代码(我个人不喜欢它),但不会投反对票,因为对于确实使用它的 ppl 来说,这是一个很好的解决方案。
            • @CoffeeTableEspresso,如果你使用 sublime,有一个名为 gitsavvy 的插件,等等......现在几乎每个编辑器都对 git 有某种支持。这就是答案的重点,您可以阅读“使用您的编辑器”。
            【解决方案8】:

            我的一个朋友制作了一个小 bash 脚本来完成这个任务。它被称为Replify

            $ replify git
            Initialized REPL for [git]
            git> init
            Initialized empty Git repository in /your/directory/here/.git/
            
            git> remote add origin https://your-url/repo.git
            
            git> checkout -b new-branch
            Switched to a new branch 'new-branch'
            
            git> push
            

            【讨论】:

            • 好的,我已经在 Umur 的回答中提到了这一点,但是在原始脚本源中使用 eval 并不是最好的主意。告诉你的朋友改用while IFS= read -r -p "git&gt; " gitcmd; do [ "x$gitcmd" != "x" ] &amp;&amp; git "$gitcmd";done
            • 将标志 -e 添加到 read 以使用 readline 编辑。遗憾的是,它似乎不记得以前的命令,而是使用实际的 shell 历史记录。我还推荐-p "$ git ",以便更容易理解您实际指挥的内容。
            【解决方案9】:

            适用于任何命令的另一种方法:使用 Ctrl+R (reverse-i-search)。

            reverse-i-search 允许您搜索命令历史记录。按下搜索字符串后重复 Ctrl+R 以使用相同的字符串重复搜索。

            您只需键入一次命令,然后您可以从命令的任何子字符串中调用该命令。在大多数情况下,只需两到三个放置良好的搜索字母,您就可以回忆起整个非常长的命令及其各种变体。除了正常使用您的 shell 外,不需要任何预配置,并且它可以自适应您使用 shell 的方式,只需键入一次完整的命令,这些命令就会自动添加到您的命令历史记录中。

            • git commit --amend: &lt;Ctrl+R&gt;am
            • git pull: &lt;Ctrl+R&gt;pu
            • git rebase --rebase-merges -i --onto origin/develop origin/develop feature/blue-header: &lt;Ctrl+R&gt;blu
            • git rebase --abort: &lt;Ctrl-R&gt;ab
            • git rebase --continue: &lt;Ctrl-R&gt;con
            • docker-compose stop &amp;&amp; git pull &amp;&amp; make &amp;&amp; docker-compose up -d: &lt;Ctrl-R&gt;up

            此外,Ctrl-R 不仅适用于 bash,还适用于许多使用 readline 库的程序(其中有很多),如 Python shell、IPython、mysql shell、psql shell、irb (ruby)、等等

            【讨论】:

              【解决方案10】:

              我非常喜欢在 ~/.bash_profile 中为我的 GitBash 使用别名。如果您采用这种方法,以下是我最喜欢的一些方法:

              # git
              alias gw='git whatchanged'
              alias gg='git grep -n -C8'
              alias ggi='git grep -i -n -C8'
              alias gb='git branch'
              alias gbd='git branch -D'
              alias gba='git branch -a'
              alias gc='git checkout'
              alias gcp='git cherry-pick'
              alias gfo='git fetch origin'
              alias s='git status'
              alias gmom='git merge origin/master'
              alias grom='git rebase origin/master'
              alias gpom='git pull origin master'
              alias pplog='git log --oneline --graph --decorate'
              

              【讨论】:

              • 提交地点:P
              • 我不包括 commitpush,因为我需要额外的几秒钟(在打字时)以确保我没有破坏某些东西
              • 提交和推送不应该能够破坏任何东西,除非你使用强制推送。但我尝试事先使用 git status。
              • 这也是我所做的,+1。虽然我很想尝试 gitsh,因为其他答案已经提到了
              • @CoffeeTableEspresso 我尊重这样一个事实,即您承认几次击键是保存更新和破坏项目之间的区别。
              【解决方案11】:

              在您的示例中,您将其与 MySql 提示进行比较。工作方式是启动 MySql 进程,然后向该进程发出命令。因此,为什么不用您选择的语言写一些类似的东西呢?下面是一个简单的 C++ 示例:

              #include <iostream>
              #include <cstdlib>
              
              int main(int argc, char *argv[]){
                  while(true){
                      std::cout << "git> ";
                      std::cout.flush();
                      std::string command;
                      std::getline(std::cin, command);
                      if(command == "exit") break;
                      std::system("git " + command);
                  }
              
                  return 0;
              }
              

              请注意,我只是从内存中写出来的,并没有用编译器检查它。可能存在一些细微的语法错误。

              【讨论】:

              • 只是我的想法。 Stack Overflow 上的任何人都应该能够自己编写这样的程序。编程语言并不重要。
              • @ThomasWeller 我绝对同意。我发布这个程序是为了准确地展示我在说什么,而不是因为它是一个难以编写的程序。
              • 如果您希望程序没有错误并具有大量功能,您将在这种方法上投入大量时间。例如,在修复初始构建失败(std::system() 需要 const char*)后,您会注意到 EOF 上有一个无限循环。您可能需要历史记录/readline 支持、选项卡补全、一些用于更改目录/设置环境变量/shell out/...等的内置函数。如果有现有软件(如本例中的 gitsh),为什么不使用它呢?跨度>
              • @nomadictype 这是一个有效的批评,但学习其他软件也是一个时间承诺。这种方法的优点是只需要几分钟就可以让它工作,而且它会完全做你期望或想要的(有变化)。
              • 失去 readline、行编辑、历史支持、能够运行像 ls 等简单命令的损失将比您节省的四次击键多得多。跨度>
              【解决方案12】:

              这是另一种方式。这也不是所要求的,但我已经使用它一段时间了,它非常好。将以下行添加到您的~/.bashrc

              complete -E -W git
              

              现在在空的 Bash 提示符下按 Tab 键将输入“git”。

              【讨论】:

              • 请注意,如果您使用的是另一个 shell,则必须将其放入相应的文件中。例如,对于zsh,您将其放入~/zshrc,对于tcsh,您将其放入~/tcshrc,等等。
              • 这实际上是真的很好这样做。这允许您随意使用所有 shell 命令,但您可以只键入例如tab statustab fetch 运行 git 命令。如果您有一些别名,您可以运行该命令,并可能将提示更改为您的“git 环境”。
              【解决方案13】:

              这并不完全符合您的要求,但您可以在 ~/.bashrc 中为您最常用的 Git 命令设置一些 shell 别名:

              alias commit='git commit'
              alias checkout='git checkout'
              ...
              

              另请注意,您可以在 Git 本身中创建别名:

              git config --global alias.ci commit
              git config --global alias.co checkout
              ...
              

              这让您可以输入git ci 而不是git commit,等等。

              【讨论】:

              • 这种方法的缺点是需要为每个 Git 命令创建一个单独的别名。
              • 只针对最常用的。我的意思是,您多久使用一次git hash-objectgit interpret-trailers?我只是提供这个作为替代方案,因为据我所知,这个问题所要求的并不真正存在。
              • 除了ci 代表commit 我还使用一个shell 别名g 代表git,这样可以减少大部分输入,让我留在我喜欢的shell 中。
              【解决方案14】:

              一个 Perl 单行代码可以做到这一点:

              perl -nE 'BEGIN {print "git > "} system "git $_"; print "git > "'
              

              这将执行您键入的任何内容,前缀为git。它会一直这样做,直到你点击^D

              【讨论】:

              • 这确实与 OP 所要求的最相似,并且在一个非常轻量级的包中!
              • 如果它与 readline 一起工作就完美了,但不幸的是它不能(不足为奇,因为这完全是围绕 Perl 的 -ne 标志的 hack)。
              • @KonradRudolph perl -MTerm::ReadLine -E '$n = Term::ReadLine -&gt; new ("git"); while ($_ = $n -&gt; readline ("git &gt; ")) {system "git $_"}'
              【解决方案15】:

              您可能想试试gitsh。从他们的自述文件中:

              gitsh 程序是 git 的交互式 shell。在gitsh 中,您可以发出任何 git 命令,甚至使用您的本地别名和配置。

              • Git 命令往往成组出现。通过在专用的 git shell 中运行 git,避免一遍又一遍地输入:
              sh$ gitsh
              gitsh% status
              gitsh% add .
              gitsh% commit -m "Ship it!"
              gitsh% push
              gitsh% ctrl-d
              sh$
              

              或者看看那里链接的其他项目:

              • git-sh - 带有 Git 提示符、别名和补全的自定义 bash shell。
              • gitsh - 一个用 Perl 编写的简单 Git shell。
              • repl - 使用 REPL 中的子命令包装任何程序。

              注意:我自己没用过。

              【讨论】:

              • grumble...repl(1) 不是 REPL。它不会评估或打印任何东西。它运行程序。
              • @Kevin 它读取用户请求,评估用户请求(通过运行程序),并打印程序的输出。这也是贝壳的作用。
              • @Yakk-AdamNevraumont:不,它肯定不会“打印程序的输出”。它将程序的标准输出连接到终端,然后程序打印自己的输出——除了程序的标准输出已经连接到终端(自动继承fork()/exec()),所以repl(1)不是甚至不做那个
              • @Kevin 我理解你的观点,但是 REPL 的严格定义将排除 大多数 各种语言的解释器“REPL”。只有在纯函数式语言中才能确保评估没有副作用,但即使在 Haskell 中,“REPL”GHCi 也会默认接受 IO 操作,并执行它们,包括打印到终端等副作用 -已连接的屏幕。
              • @Kevin repl 不是独立的 REPL;这是一种创建 REPL 系统的方法,其中repl 只是交互式组件。这公平吗?
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-12-06
              • 2021-10-11
              • 2023-03-07
              • 2021-12-17
              • 2013-01-29
              相关资源
              最近更新 更多