Git module useage help needed

I am trying to push to a remote git server all my workflow definitions for backup and version tracking, but can’t figure out how should I clone the repo, so I would be able to commit and push.

Whatever I set as repositoryPath I keep getting and error ERROR: fatal: destination path '.' already exists and is not an empty directory. what am I missing ?

Hey @userX,

Looking at the clone it looks ok and it should be creating the repo under /tmp/code but it might be worth setting that same path in the add otherwise it will try to save them into the local working directory which wouldn’t be your git project.

Let me know how you get on with the changes.

to be honest I never got that far to run the Add step as no combination of Clone repo worked, I tried relative path’s, absolute path’s tmp, and local folders, create the folder in a previous step with command and not, leave the path empty etc etc neither worked, I enabled debug log on the server and still got no closer to a solution. I run self hosted version 1.7.1, and I am just stuck at this point.

Hey @userX,

Are you using our docker image or something else? The error just looks like the parth is incorrect so it would be handy to see what the error is if you do set the path for both nodes. I would maybe start by cloneing the repo to an empty folder then in the Write Binary File node includ that path with the filename then you should be good to go.

1 Like

Hey hey, so I did move the clone to the front and it kind of worked, now I added a logic around handeling existing missing repos, but I still have two mayor issues.

Issue Nr1:
To make the workflow re-usable I used Set to store the local and remote location of the code, but I don’t know how to refer to the a different nodes output in python.

Issue Nr2:
The file write doesn’t really want to work in this example, or the git add is pointing at the wrong point, something isn’t right, what I might be missing in this flow ?

Hey @userX,

The Code nodes might be uneeded, The first one can be done in an expression and possibly the second looking at it.

Is the file write saving the files if you check the path?

Ok so removing the local path ( “code”) from the from path of the file help and now I have the files generated and added to git, but I can’t commit it yet as I have no user.email and user.name set up in the git config, do I need to do that with “Execute command” or there is an option for this in the git module, or in git credential ? I can’t see it in the git integrations docs.

Hey @userX,

The Git node has an Add Config operation that should allow you to set the config.

Hi @Jon ! Thanks for the help I now have a functional backup workflow, and while it is still not perfect ( I had to add jq to the docker image ) but it works as expected, and now I can put my mind at rest that it’s there it’s running, and can worry about making it perfect a bit later, sharing the whole workflow for further reference, feel free to make upgrade suggestions, copy re-use publish whatever.

{
  "meta": {
    "instanceId": "my_instanceid"
  },
  "nodes": [
    {
      "parameters": {
        "mode": "jsonToBinary",
        "options": {
          "useRawData": true
        }
      },
      "id": "myid"
      "name": "Move Binary Data",
      "type": "n8n-nodes-base.moveBinaryData",
      "typeVersion": 1,
      "position": [
        2340,
        580
      ]
    },
    {
      "parameters": {
        "fileName": "=code/{{ $('Generate git friendly filenames').item.json.filename }}",
        "options": {
          "append": false
        }
      },
      "id": "myid"
      "name": "Write Binary File",
      "type": "n8n-nodes-base.writeBinaryFile",
      "typeVersion": 1,
      "position": [
        2540,
        580
      ]
    },
    {
      "parameters": {
        "authentication": "gitPassword",
        "operation": "clone",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "sourceRepository": "={{ $('Set variables').item.json.repourl }}"
      },
      "id": "myid"
      "name": "Clone the repo",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        1500,
        420
      ],
      "alwaysOutputData": true,
      "credentials": {
        "gitPassword": {
          "id": "myid"
          "name": "Git account"
        }
      },
      "continueOnFail": true
    },
    {
      "parameters": {
        "operation": "add",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "pathsToAdd": "={{ $('Generate git friendly filenames').item.json.filename }}"
      },
      "id": "myid"
      "name": "Add them to git",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        2960,
        580
      ]
    },
    {
      "parameters": {
        "filters": {}
      },
      "id": "myid"
      "name": "List n8n workflows",
      "type": "n8n-nodes-base.n8n",
      "typeVersion": 1,
      "position": [
        1940,
        580
      ],
      "credentials": {
        "n8nApi": {
          "id": "myid"
          "name": "n8n itself"
        }
      }
    },
    {
      "parameters": {
        "operation": "pull",
        "repositoryPath": "code"
      },
      "id": "myid"
      "name": "Pull the repo",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        1740,
        580
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.error }}",
              "value2": "Error: Cannot use simple-git on a directory that does not exist"
            }
          ]
        }
      },
      "id": "myid"
      "name": "Is repo already exist",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        740,
        440
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.remote }}",
              "value2": "={{ $('Set variables').item.json.repourl }}"
            }
          ]
        }
      },
      "id": "myid"
      "name": "Is this the right repo",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1140,
        600
      ]
    },
    {
      "parameters": {
        "command": "=rm -rf  {{ $('Set variables').item.json.codefolder }}"
      },
      "id": "myid"
      "name": "Delete current repo",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        1360,
        680
      ]
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "return [{\"remote\": \"https://\" + str(_input.first().json[\"remote.origin.url\"].split(\"@\")[1])}]"
      },
      "id": "myid"
      "name": "construct repo url",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        600
      ],
      "alwaysOutputData": true,
      "continueOnFail": true
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "codefolder",
              "value": "code"
            },
            {
              "name": "repourl",
              "value": "https://git.domain.tld/myusername/n8n_flows"
            },
            {
              "name": "git_email",
              "value": "[email protected]"
            },
            {
              "name": "git_username",
              "value": "n8n-bot"
            }
          ]
        },
        "options": {}
      },
      "id": "myid"
      "name": "Set variables",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        360,
        440
      ]
    },
    {
      "parameters": {
        "language": "python",
        "pythonCode": "list = _input.all()\nreturn_data = []\nfor item in list:\n    data = item.json\n    filename = data[\"name\"].lower().replace(\" \",\"_\") + \".json\"\n    data[\"filename\"] = filename\n    return_data.append(data)\nreturn return_data"
      },
      "id": "myid"
      "name": "Generate git friendly filenames",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        580
      ]
    },
    {
      "parameters": {
        "operation": "listConfig",
        "repositoryPath": "={{ $json.codefolder }}"
      },
      "id": "myid"
      "name": "Check repo config",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        560,
        440
      ],
      "alwaysOutputData": true,
      "continueOnFail": true
    },
    {
      "parameters": {
        "operation": "commit",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "message": "=Automated workflow backup from N8N",
        "options": {}
      },
      "id": "myid"
      "name": "Commit",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        3560,
        580
      ]
    },
    {
      "parameters": {
        "operation": "addConfig",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "key": "user.email",
        "value": "={{ $('Set variables').item.json.git_email }}",
        "options": {
          "mode": "set"
        }
      },
      "id": "myid"
      "name": "User e-mail",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        3160,
        580
      ],
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "operation": "addConfig",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "key": "=user.name",
        "value": "={{ $('Set variables').item.json.git_username }}",
        "options": {}
      },
      "id": "myid"
      "name": "Git username",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        3360,
        580
      ]
    },
    {
      "parameters": {
        "authentication": "gitPassword",
        "operation": "push",
        "repositoryPath": "={{ $('Set variables').item.json.codefolder }}",
        "options": {}
      },
      "id": "myid"
      "name": "Push to remote",
      "type": "n8n-nodes-base.git",
      "typeVersion": 1,
      "position": [
        3760,
        580
      ],
      "credentials": {
        "gitPassword": {
          "id": "myid"
          "name": "Git account"
        }
      }
    },
    {
      "parameters": {
        "executeOnce": false,
        "command": "=jq . {{ $json.fileName }}  > {{ $json.fileName }}.tmp\nmv {{ $json.fileName }}.tmp {{ $json.fileName }}"
      },
      "id": "myid"
      "name": "Convert JSON files into git friendly  format",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        2740,
        580
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "id": "myid"
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        160,
        440
      ]
    }
  ],
  "connections": {
    "Move Binary Data": {
      "main": [
        [
          {
            "node": "Write Binary File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Binary File": {
      "main": [
        [
          {
            "node": "Convert JSON files into git friendly  format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clone the repo": {
      "main": [
        [
          {
            "node": "Pull the repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add them to git": {
      "main": [
        [
          {
            "node": "User e-mail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List n8n workflows": {
      "main": [
        [
          {
            "node": "Generate git friendly filenames",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pull the repo": {
      "main": [
        [
          {
            "node": "List n8n workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is repo already exist": {
      "main": [
        [
          {
            "node": "Clone the repo",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "construct repo url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is this the right repo": {
      "main": [
        [
          {
            "node": "Pull the repo",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Delete current repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete current repo": {
      "main": [
        [
          {
            "node": "Clone the repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "construct repo url": {
      "main": [
        [
          {
            "node": "Is this the right repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set variables": {
      "main": [
        [
          {
            "node": "Check repo config",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate git friendly filenames": {
      "main": [
        [
          {
            "node": "Move Binary Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check repo config": {
      "main": [
        [
          {
            "node": "Is repo already exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Commit": {
      "main": [
        [
          {
            "node": "Push to remote",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "User e-mail": {
      "main": [
        [
          {
            "node": "Git username",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Git username": {
      "main": [
        [
          {
            "node": "Commit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert JSON files into git friendly  format": {
      "main": [
        [
          {
            "node": "Add them to git",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.