* Fixed PHP 5.6 incompatibility introduced by latest release.
# v2.0.1
## 02/19/2019
1.[](#new)
* Added new `init` CLI command (`bin/plugin git-sync init`) (#128, thanks @LeonRyan and @alex-mohemian)
1.[](#improved)
* Allow setting a personalised commit message (#123, thanks @kyed)
* Added better directions for Azure + IIS users for the Git Binary
1.[](#bugfix)
* Fixed `LC_ALL` to use `C` instead of en_US.UTF-8`, to be more flexible (#124, #125, thanks @lambopedia)
# v2.0.0
## 10/15/2018
1. [](#new)
* Added support for new awesome Grav 1.6 Scheduler
* Added logic to display custom nested folders in wizard
* Other than `pages`, it is now possible to enable `config`, `data`, `plugins` and `themes` for synchronization. You can also add any custom folder you have in your `user` (#4, #21, #34, #58, #63, #83)
* Allow users with `admin.pages` permissions to synchronize through quick tray (#79, thanks @apfrod)
* When using Grav as committer, the user email will be now used for the commit (#81, thanks @apfrod)
* Added support for Webhook Secret (Bitbucket does not yet support them) (#72, #73, thanks @pathmissing)
* Added options to turn automatic synchronization on/off with page saves, delete and media changes (#105, thanks @AmauryCarrade)
1. [](#improved)
* Fixed alignment of the git icon in the Wizard (#115)
* Prevent Wizard modal to get canceled when clicking on the overlay background (#115)
* Quick tray icon is now smarter. If GitSync has not been initialized yet, it will take you straight to wizard, otherwise it would perform a synchronization (#115)
* Rearranged blueprint order (thanks @paulhibbitts)
* GitLab: Updated wizard instructions to be inline with the new GitLab UI (#90)
* Tweaked alignment of links in the wizard (#57)
* Properly support local branches that aren't `master` (#56)
* Allow to specify custom local_repository (default, `USER_DIR`) (#95, thanks @Hydraner, also #54, #33, #25)
* Webhook URL is now more robust and secure, by default it is generated with a random value
* Git icon from Admin has been replaced to use the `git` text icon instead of the logo
* Prevent next step if Step 1 and Step 2 are not filled in (#92)
* Added notice in Step 2 explaning what GitSync expect from the repository structure (#92)
1. [](#bugfix)
* Fixed issue where on first initialization the checkout process would error out
* Fixed issue with Pages save.
* Fixed JS error in plugins list
* Fixed nested folders not synchronizing
* Fixed issue where Wizard wouldn't work in case the `admin` path was modified (#27, #94, #77, thanks @pathmissing)
* Fixed webhook generated URL when multi-lang active (#71)
* Resolved issue with untracked/uncommited files at the root of the `sync` folder. (#101, thanks @ScottHamper)
# v1.0.4
## 08/16/2017
1. [](#new)
* CLI: Added `status` command to check config and git (#52, thanks @karfau)
* Allow local branches to be named differently than the remote branches (#48, thanks @denniswebb)
* Added support for new Admin Navigation Tray
1. [](#bugfix)
* Fixed minimum Git required version to support `--all` (#32,#49, thanks @redrohX)
# v1.0.3
## 02/21/2017
1. [](#bugfix)
* Fixed issue with new 'author' option that could trigger errors when settings were not saved. (#23)
* Fixed the 'More Details' button triggering the Modal to close instead of just expanding the details
# v1.0.2
## 02/18/2017
1. [](#new)
* It is now possible to change the committer name. You can choose between Git User, GitSync Committer Name, Grav User Name, Grav User Fullname (#14).
2. [](#improved)
* Added more documentation and description about the support of 2FA and Access Tokens (#16, #19, thanks @OleVik)
* Added 4th Generic Git choice in the wizard for self-hosted and custom git services (Gogs/Gitea) (#7 - #22 - thanks @erlepereira)
1. [](#bugfix)
* Fixed issue preventing the custom Git Binary Path from getting used (#15)
* Fixed issue with Webhook auto-generated URL where it would display double slashes in case of root domain (#15)
* Fixed issue with the modal not properly restoring the tutorial steps of the active selected service
# v1.0.1
## 01/29/2017
1. [](#bugfix)
* Changed default GitSync email for commits
# v1.0.0
## 01/25/2017
1. [](#new)
* Released plugin to stable GPM channel
# v1.0.0-rc.3
## 01/19/2017
1. [](#new)
* Added logger setting to log Git command executions
1. [](#improved)
* Improved Windows compatibility
# v1.0.0-rc.2
## 01/16/2017
1. [](#new)
* Allow to change the path for the `git` binary (#1)
* Added CLI for synchronizing `bin/plugin git-sync sync` (#2)
* More security: Git password will now get encrypted and won't load in admin
1. [](#improved)
* Wizard: Improved Bitbucket explanation about stripping out `user@` from the copied HTTPS url (#3)
1.[](#bugfix)
* Fixed potential issue when retrieving the currently installed git version
* Fixed issue that would not properly hide the password from error messages if the password contained special chars
* Fixed issue preventing the plugin to properly get setup the very first time and causing 401 error (#4)
* Workaround for error thrown when removing the plugin
**Git Sync** is a Plugin for [Grav CMS](http://github.com/getgrav/grav) that allows to seamlessly synchronize a Git repository with your Grav site, and vice-versa.
Git Sync captures any change that you make on your site and instantly updates your git repository. In the same way, Git Sync supports _webhooks_, allowing to automatically synchronize your site if the repository changes.
Thanks to this powerful bi-directional flow, Git Sync can now turn your site into a collaborative environment where the source of truth is always your git repository and unlimited collaborators and sites can share and contribute to the same content.
## Videos: Setup and Demo
| Up and Running in 2 mins | 2-way Sync Demonstration |
| ------------ | ----------------- |
| [](https://www.youtube.com/watch?v=avcGP0FAzB8) | [](https://www.youtube.com/watch?v=3fy78afacyw) |
## Installation using the GPM (Grav Package Manager)
To install git-sync simply run this command from the Grav root folder
```
bin/gpm install git-sync
```
After having installed the plugin, make sure to go in the plugin settings in order to get the Wizard configuration started.
## Features
<imgsrc="wizard.png"width="500"/>
* Easy step-by-step Wizard setup will guide you through a detailed process for setting things up
* Supported hosting services: [GitHub](https://github.com), [BitBucket](https://bitbucket.org), [GitLab](https://gitlab.com) as well as any self-hosted and git service with webhooks support.
* Private repositories
* Synchronize any folder under `user` (pages, themes, config)
* 2FA (Two-Factor Authentication) and Access Token support
* Webhooks support allow for automatic synchronization from the Git Repository with secure Webhook URL auto-generated and support for Webhook Secret (when available)
* Automatically handles simple merges behind the scenes
* Easy one-click button to reset your local changes and restores it to the actual state of the git repository
* Easy one-click button to manually synchronize
* Support for Admin Quick Tray so you can synchronize from anywhere in Admin
* Ability to customize whether GitSync should synchronize upon save or just manually
* Customize the Committer Name, choose between Git User, GitSync Commiter Name, Grav User Name and Grav user Fullname
* With the built-in Form Process action `gitsync`, you can trigger the synchronization anytime someone submits a post.
* Any 3rd party plugin can integrate with Git Sync and trigger the synchronization through the `gitsync` event.
* Built-in CLI command to automate synchronizations
* Log any command performed by GitSync to ensure everything runs smoothly or debug potential issues
# Command Line Interface
Git Sync comes with a CLI that allows to run synchronizations right within your terminal. This feature is extremely useful in case you'd like to run an autonomous periodic crontab job to synchronize with your repository.
To execute the command simply run:
```bash
bin/plugin git-sync sync
```
# Requirements
In order for the plugin to work, the server needs to run `git` 1.7.1 and above.
The PHP `exec()` and `escapeshellarg()` functions are required to be enabled.
# Sponsored by
This plugin could not have been realized without the sponsorship of [Hibbitts Design](http://www.hibbittsdesign.org/blog/) and the development of [Trilby Media](http://trilby.media).
description:Removing folders after they have been synced may cause undesired results.
default:
-pages
options:
-pages
-themes
-plugins
-config
-data
selectize:
create:true
validate:
type:commalist
Sync:
type:section
title:Automatic Synchronization Settings
underline:true
SyncNotice:
type:spacer
markdown:true
text:|
! To improve the speed of saving pages you can disable automatic sync. Then, changes to a page will not be sent to the remote repository on every save. To sync your changes to the repository tap the GitSync button (<i class="fa fa-git"></i>) in the top left of the Administration Panel, or use the below Scheduler option to add the GitSync Syncronization Job to the Scheduler (<strong>Grav 1.6 required</strong>).
sync.on_save:
type:toggle
label:Sync on Page Save
help:Sync with the remote directory when a page is saved through the admin
default:1
highlight:1
options:
1:PLUGIN_ADMIN.YES
0:PLUGIN_ADMIN.NO
validate:
type:bool
sync.on_delete:
type:toggle
label:Sync on Page Delete
help:Sync with the remote directory when a page is deleted through the admin
default:1
highlight:1
options:
1:PLUGIN_ADMIN.YES
0:PLUGIN_ADMIN.NO
validate:
type:bool
sync.on_media:
type:toggle
label:Sync on Media Changes
help:Sync with the remote directory when a media is uploaded or deleted through the admin immediately (instead of only syncing when the page is saved)
default:1
highlight:1
options:
1:PLUGIN_ADMIN.YES
0:PLUGIN_ADMIN.NO
validate:
type:bool
sync.cron_enable:
type:toggle
label:Add Sync to Scheduler
help:Add GitSync Job to the Scheduler so it can automatically perform synchronization at the given time
default:0
highlight:1
options:
1:PLUGIN_ADMIN.YES
0:PLUGIN_ADMIN.NO
validate:
type:bool
sync.cron_at:
type:cron
label:Run Sync at
help:When should the Scheduler run the automatic GitSync synchronization job
->setDescription('Initializes your git repository')
->setHelp('The <info>init</info> command runs the same git commands as the onAdminAfterSave function. Use this to manually initialize git-sync (useful for automated deployments).')
(window.webpackJsonp=window.webpackJsonp||[]).push([[1],[function(e,t){varr;r=function(){returnthis}();try{r=r||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeofwindow&&(r=window)}e.exports=r},,,function(e,t){e.exports=function(e){returnnull==e?"":e.toString()}},function(e,t){e.exports=[" ","\n","\r","\t","\f","\v"," "," ",""," "," "," "," "," "," "," "," "," "," "," ","\u2028","\u2029"," "," "," "]},,,,,,,function(e,t,r){(function(t){(function(){!function(e){"use strict";if(!e.fetch){vart={searchParams:"URLSearchParams"ine,iterable:"Symbol"ine&&"iterator"inSymbol,blob:"FileReader"ine&&"Blob"ine&&function(){try{returnnewBlob,!0}catch(e){return!1}}(),formData:"FormData"ine,arrayBuffer:"ArrayBuffer"ine};if(t.arrayBuffer)varr=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],n=function(e){returne&&DataView.prototype.isPrototypeOf(e)},o=ArrayBuffer.isView||function(e){returne&&r.indexOf(Object.prototype.toString.call(e))>-1};l.prototype.append=function(e,t){e=a(e),t=u(t);varr=this.map[e];this.map[e]=r?r+","+t:t},l.prototype.delete=function(e){deletethis.map[a(e)]},l.prototype.get=function(e){returne=a(e),this.has(e)?this.map[e]:null},l.prototype.has=function(e){returnthis.map.hasOwnProperty(a(e))},l.prototype.set=function(e,t){this.map[a(e)]=u(t)},l.prototype.forEach=function(e,t){for(varrinthis.map)this.map.hasOwnProperty(r)&&e.call(t,this.map[r],r,this)},l.prototype.keys=function(){vare=[];returnthis.forEach(function(t,r){e.push(r)}),c(e)},l.prototype.values=function(){vare=[];returnthis.forEach(function(t){e.push(t)}),c(e)},l.prototype.entries=function(){vare=[];returnthis.forEach(function(t,r){e.push([r,t])}),c(e)},t.iterable&&(l.prototype[Symbol.iterator]=l.prototype.entries);vari=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];m.prototype.clone=function(){returnnewm(this,{body:this._bodyInit})},y.call(m.prototype),y.call(w.prototype),w.prototype.clone=function(){returnneww(this._bodyInit,{status:this.status,statusText:this.statusText,headers:newl(this.headers),url:this.url})},w.error=function(){vare=neww(null,{status:0,statusText:""});returne.type="error",e};vars=[301,302,303,307,308];w.redirect=function(e,t){if(-1===s.indexOf(t))thrownewRangeError("Invalid status code");returnneww(null,{status:t,headers:{location:e}})},e.Headers=l,e.Request=m,e.Response=w,e.fetch=function(e,r){returnnewPromise(function(n,o){vari=newm(e,r),s=newXMLHttpRequest;s.onload=function(){vare,t,r={status:s.status,statusText:s.statusText,headers:(e=s.getAllResponseHeaders()||"",t=newl,e.replace(/\r?\n[\t]+/g," ").split(/\r?\n/).forEach(function(e){varr=e.split(":"),n=r.shift().trim();if(n){varo=r.join(":").trim();t.append(n,o)}}),t)};r.url="responseURL"ins?s.responseURL:r.headers.get("X-Request-URL");varo="response"ins?s.response:s.responseText;n(neww(o,r))},s.onerror=function(){o(newTypeError("Network request failed"))},s.ontimeout=function(){o(newTypeError("Network request failed"))},s.open(i.method,i.url,!0),"include"===i.credentials?s.withCredentials=!0:"omit"===i.credentials&&(s.withCredentials=!1),"responseType"ins&&t.blob&&(s.responseType="blob"),i.headers.forEach(function(e,t){s.setRequestHeader(t,e)}),s.send(void0===i._bodyInit?null:i._bodyInit)})},e.fetch.polyfill=!0}functiona(e){if("string"!=typeofe&&(e=String(e)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(e))thrownewTypeError("Invalid character in header field name");returne.toLowerCase()}functionu(e){return"string"!=typeofe&&(e=String(e)),e}functionc(e){varr={next:function(){vart=e.shift();return{done:void0===t,value:t}}};returnt.iterable&&(r[Symbol.iterator]=function(){returnr}),r}functionl(e){this.map={},einstanceofl?e.forEach(function(e,t){this.append(t,e)},this):Array.isArray(e)?e.forEach(function(e){this.append(e[0],e[1])},this):e&&Object.getOwnPropertyNames(e).forEach(function(t){this.append(t,e[t])},this)}functiond(e){if(e.bodyUsed)returnPromise.reject(newTypeError("Already read"));e.bodyUsed=!0}functionf(e){returnnewPromise(function(t,r){e.onload=function(){t(e.result)},e.onerror=function(){r(e.error)}})}functionh(e){vart=newFileReader,r=f(t);returnt.readAsArrayBuffer(e),r}functionp(e){if(e.slice)returne.slice(0);vart=newUint8Array(e.byteLength);returnt.set(newUint8Array(e)),t.buffer}functiony(){returnthis.bodyUsed=!1,this._initBody=function(e){if(this._bodyInit=e,e)if("string"==typeofe)this._bodyText=e;elseif(t.blob&&Blob.prototype.isPrototypeOf(e))this._bodyBlob=e;elseif(t.formData&&FormData.prototype.isPrototypeOf(e))this._bodyFormData=e;elseif(t.searchParams&&URLSearchParams.prototype.isPrototypeOf(e))this._bodyText=e.toString();elseif(t.arrayBuffer&&t.blob&&n(e))this._bodyArrayBuffer=p(e.buffer),this._bodyInit=newBlob([this._bodyArrayBuffer]);else{if(!t.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(e)&&!o(e))thrownewError("unsupported BodyInit type");this._bodyArrayBuffer=p(e)}elsethis._bodyText="";this.headers.get("content-type")||("string"==typeofe?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):t.searchParams&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},t.blob&&(this.blob=function(){vare=d(this);if(e)returne;if(this._bodyBlob)returnPromise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)returnPromise.resolve(newBlob([this._bodyArrayBuffer]));if(this._bodyFormData)thrownewError("could not read FormData body as blob");returnPromise.resolve(newBlob([this._bodyText]))},this.arrayBuffer=function(){returnthis._bodyArrayBuffer?d(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(h)}),this.text=function(){vare,t,r,n=d(this);if(n)returnn;if(this._bodyBlob)returne=this._bodyBlob,t=newFileReader,r=f(t),t.readAsText(e),r;if(this._bodyArrayBuffer)returnPromise.resolve(function(e){for(vart=newUint8Array(e),r=newArray(t.length),n=0;n<t.length;n++)r[n]=String.fromCharCode(t[n]);returnr.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)thrownewError("could not read FormData body as text");returnPromise.resolve(this._bodyText)},t.formData&&(this.formData=function(){returnthis.text().then(b)}),this.json=function(){returnthis.text().then(JSON.parse)},this}functionm(e,t){varr,n,o=(t=t||{}).body;if(einstanceofm){if(e.bodyUsed)thrownewTypeError("Already read");this.url=e.url,this.credentials=e.credentials,t.headers||(this.headers=newl(e.headers)),this.method=e.method,this.mode=e.mode,o||null==e._bodyInit||(o=e._bodyInit,e.bodyUsed=!0)}elsethis.url=String(e);if(this.credentials=t.credentials||this.credentials||"omit",!t.headers&&this.headers||(this.headers=newl(t.headers)),this.method=(r=t.method||this.method||"GET",n=r.toUpperCase(),i.indexOf(n)>-1?n:r),this.mode=t.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)thrownewTypeError("Body not allowed for GET or HEAD requests");this._initBody(o)}functionb(e){vart=newFormData;returne.trim().split("&").forEach(function(e){if(e){varr=e.split("="),n=r.shift().replace(/\+/g," "),o=r.join("=").replace(/\+/g," ");t.append(decodeURIComponent(n),decodeURIComponent(o))}}),t}functionw(e,t){t||(t={}),this.type="default",this.status=void0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"int?t.statusText:"OK",this.headers=newl(t.headers),this.url=t.url||"",this._initBody(e)}}("undefined"!=typeofself?self:this),e.exports=t.fetch}).call(t)}).call(this,r(0))},,function(e,t,r){varn,o;r(14),n=[r(1)],void0===(o=function(e){returnfunction(){vart,r,n,o=0,i={error:"error",info:"info",success:"success",warning:"warning"},s={clear:function(r,n){varo=d();t||a(o),u(r,o,n)||function(r){for(varn=t.children(),o=n.length-1;o>=0;o--)u(e(n[o]),r)}(o)},remove:function(r){varn=d();t||a(n),r&&0===e(":focus",r).length?f(r):t.children().length&&t.remove()},error:function(e,t,r){returnl({type:i.error,iconClass:d().iconClasses.error,message:e,optionsOverride:r,title:t})},getContainer:a,info:function(e,t,r){returnl({type:i.info,iconClass:d().iconClasses.info,message:e,optionsOverride:r,title:t})},options:{},subscribe:function(e){r=e},success:function(e,t,r){returnl({type:i.success,iconClass:d().iconClasses.success,message:e,optionsOverride:r,title:t})},version:"2.1.4",warning:function(e,t,r){returnl({type:i.warning,iconClass:d().iconClasses.warning,message:e,optionsOverride:r,title:t})}};returns;functiona(r,n){returnr||(r=d()),(t=e("#"+r.containerId)).length?t:(n&&(t=function(r){return(t=e("<div/>").attr("id",r.containerId).addClass(r.positionClass)).appendTo(e(r.target)),t}(r)),t)}functionu(t,r,n){varo=!(!n||!n.force)&&n.force;return!(!t||!o&&0!==e(":focus",t).length||(t[r.hideMethod]({duration:r.hideDuration,easing:r.hideEasing,complete:function(){f(t)}}),0))}functionc(e){r&&r(e)}functionl(r){vari=d(),s=r.iconClass||i.iconClass;if(void0!==r.optionsOverride&&(i=e.extend(i,r.optionsOverride),s=r.optionsOverride.iconClass||s),!function(e,t){if(e.preventDuplicates){if(t.message===n)return!0;n=t.message}return!1}(i,r)){o++,t=a(i,!0);varu=null,l=e("<div/>"),h=e("<div/>"),p=e("<div/>"),y=e("<div/>"),m=e(i.closeHtml),b={intervalId:null,hideEta:null,maxHideTime:null},w={toastId:o,state:"visible",startTime:newDate,options:i,map:r};returnr.iconClass&&l.addClass(i.toastClass).addClass(s),function(){if(r.title){vare=r.title;i.escapeHtml&&(e=v(r.title)),h.append(e).addClass(i.titleClass),l.append(h)}}(),function(){if(r.message){vare=r.message;i.escapeHtml&&(e=v(r.message)),p.append(e).addClass(i.messageClass),l.append(p)}}(),i.closeButton&&(m.addClass(i.closeClass).attr("role","button"),l.prepend(m)),i.progressBar&&(y.addClass(i.progressClass),l.prepend(y)),i.rtl&&l.addClass("rtl"),i.newestOnTop?t.prepend(l):t.append(l),function(){vare="";switch(r.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}l.attr("aria-live",e)}(),l.hide(),l[i.showMethod]({duration:i.showDuration,easing:i.showEasing,complete:i.onShown}),i.timeOut>0&&(u=setTimeout(g,i.timeOut),b.maxHideTime=parseFloat(i.timeOut),b.hideEta=(newDate).getTime()+b.maxHideTime,i.progressBar&&(b.intervalId=setInterval(x,10))),i.closeOnHover&&l.hover(C,T),!i.onclick&&i.tapToDismiss&&l.click(g),i.closeButton&&m&&m.click(function(e){e.stopPropagation?e.stopPropagation():void0!==e.cancelBubble&&!0!==e.cancelBubble&&(e.cancelBubble=!0),i.onCloseClick&&i.onCloseClick(e),g(!0)}),i.onclick&&l.click(function(e){i.onclick(e),g()}),c(w),i.debug&&console,l}functionv(e){returnnull==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}functiong(t){varr=t&&!1!==i.closeMethod?i.closeMethod:i.hideMethod,n=t&&!1!==i.closeDuration?i.closeDuration:i.hideDuration,o=t&&!1!==i.closeEasing?i.closeEasing:i.hideEasing;if(!e(":focus",l).length||t)returnclearTimeout(b.intervalId),l[r]({duration:n,easing:o,complete:function(){f(l),clearTimeout(u),i.onHidden&&"hidden"!==w.state&&i.onHidden(),w.state="hidden",w.endTime=newDate,c(w)}})}functionT(){(i.timeOut>0||i.extendedTimeOut>0)&&(u=setTimeout(g,i.extendedTimeOut),b.maxHideTime=parseFloat(i.extendedTimeOut),b.hideEta=(newDate).getTime()+b.maxHideTime)}functionC(){clearTimeout(u),b.hideEta=0,l.stop(!0,!0)[i.showMethod]({duration:i.showDuration,easing:i.showEasing})}functionx(){vare=(b.hideEta-(newDate).getTime())/b.maxHideTime*100;y.width(e+"%")}}functiond(){returne.extend({},{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'<button type="button">×</button>',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1},s.options)}functionf(e){t||(t=a()),e.is(":visible")||(e.remove(),e=null,0===t.children().length&&(t.remove(),n=void0))}}()}.apply(t,n))||(e.exports=o)},function(e,t){e.exports=function(){thrownewError("define cannot be used indirect")}},function(e,t,r){varn=r(3),o=r(4),i=r(16),s=r(17);e.exports=function(e,t){returne=n(e),i(s(e,t=t||o),t)}},function(e,t,r){varn=r(3),o=r(4);e.exports=function(e,t){e=n(e),t=t||o;for(varr,i,s=0,a=e.length,u=t.length,c=!0;c&&s<a;)for(c=!1,r=-1,i=e.charAt(s);++r<u;)if(i===t[r]){c=!0,s++;break}returns>=a?"":e.substr(s,a)}},function(e,t,r){varn=r(3),o=r(4);e.exports=function(e,t){e=n(e),t=t||o;for(varr,i,s=e.length-1,a=t.length,u=!0;u&&s>=0;)for(u=!1,r=-1,i=e.charAt(s);++r<a;)if(i===t[r]){u=!0,s--;break}returns>=0?e.substring(0,s+1):""}}]]);
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
This wizard will guide you through a few simple steps that will help you set up the plugin and your <iclass="fa fa-fw fa-git"></i> repository. When done you will have a bi-directional synchronization link between your site and the <iclass="fa fa-fw fa-git"></i> repository.
Select the <iclass="fa fa-fw fa-git"></i> repository-hosting service that you will be using to remotely store your data. Once you picked one, insert the username and password or token to access the service. Passwords are saved securely.
<h3>Access Tokens and 2FA (Two-factor Authentication)</h3>
<p>If you have never used Access Tokens or don't know what 2FA is, you most likely only need your <strong>regular password</strong> for the field above. You can then skip this step and press <strong>Next</strong> to continue.</p>
<p>With GitSync you have the option to use an Access Token instead of your password, however if you have <strong>2FA (Two-factor authentication)</strong> enabled for your git service, you can use Access Tokens.</p>
<p>Using a token is more secure than using your password, because you can limit what can be done using it and it can be revoked without worrying about changing the password. As we are just syncing, we only need to give it read-and-write access to repositories and webhooks.
</p>
<divclass="hidden-step-github hidden">
<h4>GitHub</h4>
<p>
With <ahref="https://help.github.com/articles/creating-an-access-token-for-command-line-use/"target="_blank">GitHub's Personal Access Tokens</a>, select the following Scopes:
</p>
<ul>
<li><iclass="fa fa-check-square-o"></i><code>repo</code> (Full control of private repositories)</li>
<li><iclass="fa fa-check-square-o"></i><code>admin:repo_hook</code> (Full control of repository hooks)</li>
</ul>
</div>
<divclass="hidden-step-bitbucket hidden">
<h4>Bitbucket</h4>
<p>
With <ahref="https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html"target="_blank">BitBucket's App Passwords</a>, select the following Permissions:
<li><iclass="fa fa-check-square-o"></i><code>Read and write</code></li>
</ul>
</li>
</ul>
</div>
<divclass="hidden-step-gitlab hidden">
<h4>GitLab</h4>
<p>
For <ahref="https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html"target="_blank">GitLab's Personal Access Tokens</a> select the following Scopes:
</p>
<ul>
<li><iclass="fa fa-check-square-o"></i><code>API</code> (Access your API)</li>
</ul>
</div>
<divclass="hidden-step-allothers hidden">
<h4>Other Git Repositories</h4>
<p>Usually under your profile settings is where you can generate a new Access Token. You want to ensure that you have enough read/write access for the repository as well as <code>webhook</code> access</p>
</div>
</div>
</div>
<p>
Press <strong>Next</strong> to continue.
</p>
</div>
</div>
<divclass="step-2">
<h1>Step 2 - Setting up the Repository</h1>
<divclass="panel hidden disabled">
<p>
If you already have a repository set up and ready to use, you can skip this step. Otherwise, please follow these steps:
</p>
<divclass="wizard-padding">
<ol>
<li>If you are creating a new repository (recommended), you must create an initial commit.
<ul>
<li>The service providers often ask you to do this when you made it.</li>
<li>Check the box that says Initialize repository with a README or .gitignore</li>
<li>This is required for GitSync to work.</li>
</ul>
</li>
<li>Once you have made your repository, copy the full HTTPS URL and paste it into the box below.
<ul>
<li>Most services offer both SSH and HTTPS addresses, <strong>but only HTTPS is supported at this time</strong>.</li>
Follow the instructions on <ahref="https://help.github.com/articles/creating-a-new-repository/"target="_blank">GitHub Help</a> to create a new GitHub repository.
Follow the instructions on <ahref="https://confluence.atlassian.com/bitbucket/create-a-git-repository-759857290.html"target="_blank">Atlassian Documentation</a> to create a new Bitbucket repository. Make sure you select <strong>Git</strong> as repository type.
GitLab calls repositories "Projects". Follow the instructions on <ahref="https://docs.gitlab.com/ce/gitlab-basics/create-project.html"target="_blank">GitLab Documentation</a> to create a new GitLab repository.
When you copy the HTTPS URL from Bitbucket, it also adds <code>your-user@</code> at the beginning of the URL which is not needed and should be removed. The URL be something like <code>https://bitbucket.org/your-user/your-repository.git</code>
A Webhook synchronizes the site when a change happens in the repository, and is set up at the service provider. This is a special URL to your site, that you add to your repository's settings. We've auto-generated one for you below, but you can change this to whatever you'd like.</p>
<li>Head to the repository on Bitbucket and click on <code><iclass="fa fa-cog"></i> Settings</code> in the sidebar (if the sidebar is collapsed, this is represented by just a <iclass="fa fa-cog"></i>)</li>
<li>Click on <code>Webhooks</code> on the left sidebar of the page that just loaded</li>
<li>Click on the <code>Add webhook</code>-button at the top</li>
<li>
Fill out the form as follows
<ul>
<li><strong>Title</strong>: <em>any title you like, eg. GitSync</em></li>
<li>Head to the repository on GitLab and click on <code><iclass="fa fa-cog"></i><strong>Settings</strong></code> dropdown-button from the page sidebar</li>
<li>Select <code>Integrations</code> (or <code>Webhooks</code> if <v8.16)fromthelist</li>
This folder contains all the user accounts of the site.
</p>
<pclass="description-config hidden">
This folder contains all the site configurations.
</p>
<pclass="description-data hidden">
This folder contains all the stored data from plugins.
</p>
<pclass="description-pages hidden">
This folders contains all the pages of your site.
</p>
<pclass="description-plugins hidden">
This folders contains all the plugins installed in your site.
</p>
<pclass="description-themes hidden">
This folders contains all the themes installed in your site.
</p>
<pclass="info warning description-accounts description-config description-data hidden">Careful! This folder can contain sensitive data and synchronizing it will potentially expose the data publicly. Private repository recommended.</p>
<pclass="info alert description-themes hidden">Note that changes happening in this folder can't be detected automatically by GitSync, therefore a manual synchronization will be required.</p>
The <strong>GitSync</strong> plugin requires the <iclass="fa fa-fw fa-git"></i> (Git) binary to be installed and accessible in order to work.</p>
<p>
If <iclass="fa fa-fw fa-git"></i> (Git) is missing from your hosting provider, you should open a ticket with them and request it to be installed.
</p>
<p>You can also specify a custom path in the Advanced section down below at the <strong>Git Binary Path</strong> field. If you are using <strong>Windows</strong> (VM, Azure or a local setup), you might have to change the location accordingly (quotes do matter), for example: <br/><code>"D:\Program Files\Git\bin\git.exe"</code>.</p>
To add this package as a local, per-project dependency to your project, simply add a dependency on `sebastian/git` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Git 1.0: