51

I was wondering if anyone has used GitHub as a version control system, when writing a large document via TeXstudio or Texmaker?

RStudio for example has a plugin that allows R projects to be pushed and pulled from the GitHub repository, making it very easy to manage committed changes, and committing them to the actual repo.

Is there a way to achieve this easily with a LaTeX document 'project'?

36

You can run custom commands in Texmaker (User -> User Commands) as well as TeXstudio (Configure -> Build -> User Commands). With that it should be possible to call Git command line tools from within the editor. Moreover in TeXstudio, you can combine this with scripting and triggers, which allows you to automatically trigger these actions e.g. on file save.

If you tell me which git commands you need, I could provide example code.

Edit:

Below is an example for TeXstudio, in which the commands are called via scripting. Create the scripts at User Macros -> Edit Macros.... Since I'm not into git, I don't know if the actual git calls are correct, however it should illustrate the idea.

Pull:

Git pull command

A simple plain call to an external program. On first execution of the script TXS will ask you if you trust the script to execute external programs.

Push:

Git push command

This a bit more fancy. First, the script asks the user for a commit comment. Second, the trigger ?save-file means that the script is called everytime you save a file.

Of course, you can further extend the scripts according to your needs.

  • Thanks, just the standard push / pull and commit functionality.. – Nicholas Hamilton May 5 '13 at 12:23
  • I am getting an error being thrown: Not a git repository (or any of the parent directories): .git, but I have set up a .git repository, and can push and pull from command line. – Nicholas Hamilton May 6 '13 at 16:03
  • Probably need to set the working directory somehow – Nicholas Hamilton May 6 '13 at 16:30
  • There is currently no official way to set the working dir. However, you can try to hack around this: A second argument to runCommand is interpreted as main file of the project and its path is used as working dir. So you can try runCommand("git pull", "d:\\yourpath\\dummy.tex"). - Afaik dummy.tex doesn't even have to exist, but I'm not sure about this. – Tim Hoffmann May 7 '13 at 17:24
  • did the trick with: buildManager.runCommand("git push origin master", editor.fileName()) – Nicholas Hamilton May 7 '13 at 19:51
11

There is an available script on TeXstudio_wiki for commit and push. It shows a drop menu for the user to select action of two; "commit" or "Commit with Push". You can run it manually or using a trigger like ?save-file or ?close-file

Here is the script

%SCRIPT
choisedialog = UniversalInputDialog(["Commit","Commit with Push"],"Git","choiseGIT")
choisedialog.setWindowTitle("Git")
choise = choisedialog.get("comment")
if (choisedialog.exec() != null) {
    if (choisedialog.get("choiseGIT") == "Commit") {
        dialog = new UniversalInputDialog()
        dialog.setWindowTitle("Git commit / push")
        dialog.add("Committed by TeXstudio", "Comment", "comment")
        dialog.add(true, "Commit all Files","allfiles")
            if (dialog.exec() != null) {
                comment = dialog.get("comment")
                if ((dialog.get("allfiles")) == true){
                    buildManager.runCommand("git commit -a -m \"" + comment + "\"", editor.fileName())
                }else{
                    buildManager.runCommand("git commit " + editor.fileName() + " -m \"" + comment + "\"", editor.fileName())
                }
    }
} else
    if (choisedialog.get("choiseGIT") == "Commit with Push") {
        dialog = new UniversalInputDialog()
        dialog.setWindowTitle("Git commit / push")
        dialog.add("Committed by TeXstudio", "Comment", "comment")
        dialog.add("master", "Branch", "branch")
        dialog.add(true, "Commit all Files","allfiles")
            if (dialog.exec() != null) {
                comment = dialog.get("comment")
                branch = dialog.get("branch")
                    if ((dialog.get("allfiles")) == true){
                buildManager.runCommand("git commit -a -m \"" + comment + "\"", editor.fileName())
                }else{
                buildManager.runCommand("git commit " + editor.fileName() + " -m \"" + comment + "\"", editor.fileName())
                }
                buildManager.runCommand("git push origin \"" + branch +"\"", editor.fileName())
            }
   }
}
5

In case you just need to commit from TeXstudio and are willing to do all things more complicate with a terminal or some other external tool, here a quick hack to get git into TeXstudio (basically by disguising it as svn):

1) In the preferences change the SVN command to you local git:

enter image description here

2) In your $HOME/.gitconfig set the following alias

[alias]
    ci = commit

3) Now you can happily commit with Check in... from the TeXstudio menu

enter image description here

This will execute the command

 /usr/local/git/bin/git ci -m "my commit message" "/pathtofile..."

4) To access this either assign a keyboard shortcut, add it to the menu bar or got to file->svn->check in...

enter image description here

  • where is the commit menu? – skan Nov 28 '16 at 13:06
  • @skan see the edit, is this what you are looking for? – user36296 Nov 28 '16 at 13:11
  • I had tried that but when I use svn update I get the error "git: 'up' is not a git command." and other commands don't seem to do anything. I've already configured texstudio's option command -> svn -> git. Maybe I need to define some git alias? – skan Nov 28 '16 at 13:14
  • @skan As written in the first line of my answer this is "just need to commit", no other functionalities. – user36296 Nov 28 '16 at 13:17
  • OK, but if you commit is because you could want to fetch/pull that commits. – skan Nov 28 '16 at 13:19
4

Complementing the other answers, I changed their macros in order to (i) show the output of Git commands at the message panel of TeXstudio by using > txs:///messages; (ii) call xterm1 for the Git commands that need input, such as a password; and (iii) use the great tool Git LaTeXdiff to generate PDF diffs of the last pulled revision and the previous one, or the last pulled revision and the working directory.

1. xterm seems to be available on most Linux-based operating systems. See https://stackoverflow.com/a/1105033/2448553

Git pull:

%SCRIPT
buildManager.runCommand("xterm -e \"git pull; read -n1\"", editor.fileName())

Diff pulled as PDF (requires Git LaTeXdiff):

%SCRIPT
fileNameWithPath = editor.fileName()
fileName = fileNameWithPath.substring(fileNameWithPath.lastIndexOf("/") + 1)
buildManager.runCommand("git latexdiff --main " + fileName + " -b --ignore-latex-errors --latexopt \"-shell-escape\" HEAD~1 > txs:///messages", editor.fileName())

Diff working file as PDF (requires Git LaTeXdiff):

%SCRIPT
fileNameWithPath = editor.fileName()
fileName = fileNameWithPath.substring(fileNameWithPath.lastIndexOf("/") + 1)
buildManager.runCommand("git latexdiff --main " + fileName + " -b --ignore-latex-errors --latexopt \"-shell-escape\" HEAD -- > txs:///messages", editor.fileName())

Git commit added:

%SCRIPT
dialog = new UniversalInputDialog()
dialog.setWindowTitle("Git commit")
dialog.add("-m \"Committed within TeXstudio\"", "Comment: -m \"line0\" -m \"line1\" ...", "comment")
if (dialog.exec() != null) {
    comment = dialog.get("comment")
    buildManager.runCommand("git commit " + editor.fileName() + " " + comment + " > txs:///messages", editor.fileName())
}

Git commit all tracked:

%SCRIPT
dialog = new UniversalInputDialog()
dialog.setWindowTitle("Git commit all")
dialog.add("-m \"Committed within TeXstudio\"", "Comment: -m \"line0\" -m \"line1\" ...", "comment")
if (dialog.exec() != null) {
    comment = dialog.get("comment")
    buildManager.runCommand("git commit -a " + comment + " > txs:///messages", editor.fileName())
}

Git push:

%SCRIPT
buildManager.runCommand("xterm -e \"git push origin master; read -n1\"", editor.fileName())

Git status:

%SCRIPT
buildManager.runCommand("git status > txs:///messages", editor.fileName())

Git diff:

%SCRIPT
buildManager.runCommand("git diff HEAD > txs:///messages", editor.fileName())
  • 1
    @kassem and alessander-botti-benevides. These scripts work great for committing tracked files with single line comments. How do I do multi-line comments? Typing \n in the text field did not work. – Harsh Nov 25 '17 at 18:11
  • 1
    @Harsh, can you please try the solution explained here ? It would work in case you want a predefined number of lines in your comments. – Alessander Botti Benevides Nov 25 '17 at 18:23
  • @Harsh, I just changed the answer with a more general solution. Can you confirm that it works? – Alessander Botti Benevides Nov 25 '17 at 19:14
  • Yes, it works perfectly. edit [I was about to mention the space, but it seems you fixed it on your own.] :) – Harsh Nov 25 '17 at 19:58
  • This solution you mentioned allows multiple paragraphs but not exactly single linebreaks. But at least its better than a one-line comment and should be good enough for most cases. Thanks a lot. – Harsh Nov 25 '17 at 20:14
0

It happened to me that the scripts here failed when doing the push because I have no username or password. Just in case somebody had the same problem, here is the solution:

git config --global credential.helper cache

And then making a push with git, it will ask you for a username and password and after that it will save the data into your pc so you never have to put them again.

More info: https://help.github.com/articles/caching-your-github-password-in-git/

0

The other answers already show how to pull, diff, commit, push, commit and push and what not.
Here I present a script to initialise an already existing TeX 'project' folder as a git repo.
This script will init git, configure name/email and optionally setup remote. After running this script with any file in your project open, you can start to commit to your project.

Git Init

%SCRIPT
buildManager.runCommand("git init" , editor.fileName())

namedialog = new UniversalInputDialog()
namedialog.setWindowTitle("Author Details")
namedialog.add("A U Thor", "Author Name: ", "name")
if (namedialog.exec() != null) {
    name  = namedialog.get("name")
    namestr  = " \""+name+"\" "
    buildManager.runCommand("git config user.name " + namestr + " > txs:///messages", editor.fileName())
}

emaildialog = new UniversalInputDialog()
emaildialog.setWindowTitle("Author Details")
emaildialog.add("author", "Email:", "emailid")
emaildialog.add("example.com", "@", "domain")
if (emaildialog.exec() != null) {
    emailid  = emaildialog.get("emailid") 
    domain   = emaildialog.get("domain")
    email = emailid + "@@" + domain
    emailstr = " \""+email+"\" "
    buildManager.runCommand("git config user.email " + emailstr + " > txs:///messages", editor.fileName())
}

remotedialog = new UniversalInputDialog()
remotedialog.setWindowTitle("Setup Remote")
remotedialog.add(false, "Set remote now?","remotechoice")
remotedialog.add("https://github.com/USERNAME/REPOSITORY.git", "Remote Git URL: (ex https://github.com/USERNAME/REPOSITORY.git)", "remotegiturl")
if (remotedialog.exec() != null) {
    if ((remotedialog.get("remotechoice")) == true){
        remotegiturl = remotedialog.get("remotegiturl")
        buildManager.runCommand("git remote add --track master origin " + remotegiturl + " > txs:///messages", editor.fileName())
    }
}

Take a look at this answer if you are not sure where to put the above code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.