Character Vault
Any Concept / Any System
Compendium
Your System Come To Life
Roll20 for Android
Streamlined for your Tablet
Roll20 for iPad
Streamlined for your Tablet

Personal tools

Difference between revisions of "Short Git Guide"

From Roll20 Wiki

Jump to: navigation, search
m (Commonly used commands: log, reflog, cherry-pick)
m (link to GitHub guide more prominent)
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This is a short guide on how to work with Git/GitHub locally on your computer, and how to update your fork of {{repo|Roll20/roll20-character-sheets Roll20's GitHub Repository}}, using the Git Command Line(CLI).  
+
{{revdate}}This is a short guide on how to work with Git/GitHub locally on your computer, and how to update your fork of {{repo|Roll20/roll20-character-sheets Roll20's GitHub Repository}}, using the Git Command Line(CLI).  
{{NavSheetDoc}}
+
 
The guide is aimed towards people who want to work with Roll20's [[BCS|Character Sheets]] and be able to interact with Roll20's Github & Git through the command line(CLI). It's recommended by those who do lots of work on character sheets and/or juggles more that one sheet at a time.
+
{{clear}}
 +
{{NavSheetDoc}}The guide is aimed towards people who want to work with Roll20's [[BCS|Character Sheets]] and be able to interact with Roll20's Github & Git through the command line(CLI). It's recommended by those who do lots of work on character sheets and/or juggles more that one sheet at a time.
 +
 
 +
'''[[Beginner's Guide to GitHub]]''' is the other guide focusing on the GitHub part.
  
 
==Why Git CLI instead of GitHub Desktop?==
 
==Why Git CLI instead of GitHub Desktop?==
 
* Git command line(CLI) have more guides & [https://git-scm.com/docs documentation] than the GitHub Desktop/Browser
 
* Git command line(CLI) have more guides & [https://git-scm.com/docs documentation] than the GitHub Desktop/Browser
* Using the CLI makes it easier to troubleshooting, as you clearly know what steps you took, and can see the messages or error message the CLI gives back, which you can then search for on the web or share with others
+
* Using the CLI makes it easier to troubleshoot, as you clearly know what steps you took, and can see the messages or error message the CLI gives back, which you can then search for on the web or share with others
* Learning to use Git makes you have a better understanding of how Git/GitHub works. GitHub is essentially a website hosting Git, with a few extra features.
+
* Learning to use Git gives you a better understanding of how Git and GitHub works. GitHub is essentially a website hosting Git, with a few extra features.
  
 
== Reading this guide ==
 
== Reading this guide ==
 
* In most places/steps, it's first written in bold the action to be done, and afterwards an explanation of what it does, and why it's done. This is to make revisiting the  guide quicker when you already remember what each step means, but don't remember the exact commands/actions or their order.  
 
* In most places/steps, it's first written in bold the action to be done, and afterwards an explanation of what it does, and why it's done. This is to make revisiting the  guide quicker when you already remember what each step means, but don't remember the exact commands/actions or their order.  
 
* Start with reading the guide's [[#Glossary|Glossary]] to understand commonly used words or phrases in the guide. If you encounter words you don't understand, google for it together with "Git" or "Github", as it is likely a term linked to them. The author of the guide has English as a second language.  
 
* Start with reading the guide's [[#Glossary|Glossary]] to understand commonly used words or phrases in the guide. If you encounter words you don't understand, google for it together with "Git" or "Github", as it is likely a term linked to them. The author of the guide has English as a second language.  
* The GitHub repository for Character Sheets are used as an example here, but it works the same with any other GitHub project you have forked, such as Roll20's API Script repo.
+
* The [https://github.com/Roll20/roll20-character-sheets GitHub repository for Character Sheets] are used as an example here, but it works the same with any other GitHub project you have forked, such as Roll20's [https://github.com/Roll20/roll20-api-scripts API Script repo].
 
* This guide is made with Linux in mind, but should work universally, if you install & setup Git on your computer with the unix-compatible option. In some places help for Windows-users are linked, while Linux-users are assumed to knowing or figure out the basics.  
 
* This guide is made with Linux in mind, but should work universally, if you install & setup Git on your computer with the unix-compatible option. In some places help for Windows-users are linked, while Linux-users are assumed to knowing or figure out the basics.  
  
 
== First Time Setup ==
 
== First Time Setup ==
If you've already worked with a GitHub desktop or other graphical user interface, some steps are redundant, and should be skipped if it seems to create duplicates. The setup in '''Step 7.''' will be needed for the "Update your Fork"-section if you otherwise already have a github fork and a local copy.
+
If you've already worked with a GitHub desktop or other graphical user interface, some steps are redundant, and should be skipped if it seems to create duplicates. The setup in '''Step 7.''' will be needed for the "Update your Fork"-section if you otherwise already have a github fork and a local copy. The steps below outline how to clone the entire repository onto your computer. For most users, this is not necessary. After completing '''Step 6''', see the [[#Sparse Checkout|Sparse Checkout]] section for a series of alternate setup instructions to only clone the files you need.
  
 
# '''Have your own [https://github.com/ GitHub account], and have a fork created from Roll20's repository.''' (When logged into GitHub, press the "fork" icon in the upper left corner of {{repo|Roll20/roll20-character-sheets this page}}. It will ask you to name your fork, and my recommendation is to keep the default name, as it will keeps things simple later). Now you have your own fork of the repo, that you can do whatever you want with, but it's still only on the internet, and we want to make a local copy on your computer.
 
# '''Have your own [https://github.com/ GitHub account], and have a fork created from Roll20's repository.''' (When logged into GitHub, press the "fork" icon in the upper left corner of {{repo|Roll20/roll20-character-sheets this page}}. It will ask you to name your fork, and my recommendation is to keep the default name, as it will keeps things simple later). Now you have your own fork of the repo, that you can do whatever you want with, but it's still only on the internet, and we want to make a local copy on your computer.
Line 22: Line 25:
 
# '''Open up a command line prompt/interface(CLI) in this folder.''' [https://www.thewindowsclub.com/how-to-open-command-prompt-from-right-click-menu Windows guide]
 
# '''Open up a command line prompt/interface(CLI) in this folder.''' [https://www.thewindowsclub.com/how-to-open-command-prompt-from-right-click-menu Windows guide]
 
# '''Copy the URL for your GitHub fork.''' Open up your browser and navigate to your Github Fork. On the left side is a green "Clone or Download" button, and if pressed, show an url that ends in ".git", which you will need in the next step. Copy it somewhere easily accessible for Step 6. (it should look something like <code>https://github.com/YourGitHubUserName/roll20-character-sheets.git</code>)  
 
# '''Copy the URL for your GitHub fork.''' Open up your browser and navigate to your Github Fork. On the left side is a green "Clone or Download" button, and if pressed, show an url that ends in ".git", which you will need in the next step. Copy it somewhere easily accessible for Step 6. (it should look something like <code>https://github.com/YourGitHubUserName/roll20-character-sheets.git</code>)  
# '''Type <code>git clone </code> and the url you have from Step 5.''' (for me this would look like: <code>git clone https://github.com/Anduh/roll20-character-sheets.git</code>). Now git is downloading and making you a local copy of your GitHub repository, and it may take some time. This will automatically set your GitHub fork as the default remote (called "origin"). When you later use commands like <code>git push</code> or <code>git fetch</code>, it will act as if you had typed <code>git push origin</code> or <code>git fetch origin</code>, interacting with your GitHub fork. More on this later.
+
# '''Type <code>git clone </code> and the url you have from Step 5.''' (for github user Anduh this would look like: <code>git clone https://github.com/Anduh/roll20-character-sheets.git</code>). Now git is downloading and making you a local copy of your GitHub repository, and it may take some time. This will automatically set your GitHub fork as the default remote (called "origin"). When you later use commands like <code>git push</code> or <code>git fetch</code>, it will act as if you had typed <code>git push origin</code> or <code>git fetch origin</code>, interacting with your GitHub fork. More on this later.
 
# '''Navigate your CLI to be inside the folder created in Step 6.'''
 
# '''Navigate your CLI to be inside the folder created in Step 6.'''
 
# '''Type in <code>git remote add upstream https://github.com/Roll20/roll20-character-sheets.git </code>.''' This will set up Roll20's repository as an remote called <code>upstream</code> for your local copy, where you can pull updates from. This will be used later in the "update your Fork" section.
 
# '''Type in <code>git remote add upstream https://github.com/Roll20/roll20-character-sheets.git </code>.''' This will set up Roll20's repository as an remote called <code>upstream</code> for your local copy, where you can pull updates from. This will be used later in the "update your Fork" section.
 +
 +
===Additional Configs===
 +
Other configs and setup that can be nice:
 +
 +
'''Skip {{c|--set-upstream origin}} when pushing new branch to Github'''<br>
 +
Starting from Git 2.37.0, you can run just {{c|git push}} to push new branches. No more {{c|--set-upstream origin}} or need to setup complicated aliases.{{source|https://twitter.com/JI/status/1546948817462800384 1}} Enable with:<br>
 +
{{c|git config --global --add --bool push.autoSetupRemote true}}
 +
 +
* [https://www.git-scm.com/book/en/v2/Customizing-Git-Git-Configuration Git Configuration]
 +
** [https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-config Git Configs - Atlassian]
 +
 +
'''Git Aliases'''<br>
 +
Make aliases to longer commands you need often or often forget. Configure new aliases with command like this:
 +
<pre data-language="bash">
 +
git config --global alias.cmsg 'git commit -m'
 +
git config --global alias.co checkout
 +
git config --global alias.cm 'checkout master'
 +
git config --global alias.pullr20 'pull upstream master'
 +
git config --global alias.fixmaster 'reset --hard upstream/master'
 +
</pre>
 +
If you do the above commands, you now have shortcuts for some common commands shown in this guide.
 +
* [https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases Git Aliases]
 +
** [https://snyk.io/blog/10-git-aliases-for-faster-and-productive-git-workflow/ 10 git aliases for a faster and productive git workflow]
 +
 +
'''Example situation:''' You've been working on an ExampleRPG update in branch {{c|exRPG-1-40}} for a few weeks, and now want to quickly submit a typo fix to the GenericQuest sheet, you'd probably do commands like:
 +
<pre data-language="bash">
 +
git add .  //stage all current changes
 +
git cmsg "ExampleRPG 1.40 - styling Skills-section WIP"  // commit changes using one of our aliases
 +
git cm  // checkout to master-branch
 +
git pullr20 // pull latest changes from the roll20 repo
 +
git co -b GenericQuest-weapontypo // create new branch for our GenericQuest changes
 +
// do the edits you need
 +
git add .
 +
git cmsg "GenericQuest - fix typo in weapons"
 +
git push // push your changes to your github, automatically creates new branch there if you've setup the config from the above section, otherwise the CLI will suggest you the command which you can copy and paste
 +
git co exRPG-1-40 //go back to your original branch to continue on your ExampleRPG update
 +
</pre>
 +
If you haven't setup any of the aliases nor the {{c|push.autoSetupRemote true}} setting, you'd have to use the full commands for each:
 +
{| role="presentation" class="wikitable mw-collapsible mw-collapsed"
 +
| Commands w/o aliases or autoSetupRemote
 +
|-
 +
| <pre data-language="bash">
 +
git add .
 +
git commit -m "ExampleRPG 1.40 - styling Skills-section WIP"
 +
git checkout master
 +
git pull upstream master
 +
git checkout -b GenericQuest-weapontypo
 +
// do the edits you need
 +
git add .
 +
git commit -m "GenericQuest - fix typo in weapons"
 +
git push --set-upstream origin GenericQuest-weapontypo
 +
git checkout exRPG-1-40
 +
</pre>
 +
|}
 +
 +
'''Global vs Local'''<br>
 +
You might not want to use all settings or aliases in all git repositories, so instead of using {{c|--global}}(user setting for any git repo), you could instead use {{c|--local}} to save repository-specific settings. {{source|https://stackoverflow.com/a/66108560/10281722 stackoverflow}}
 +
 +
== Sparse Checkout ==
 +
The character sheet and API repositories have grown to massive sizes in the years since they were initially created. At the time of writing, the Character Sheet repository contained 1006 sheets and was several GB in size. It is very unlikely that you need, or want, all of those files on your computer's hard disk. This is where git's <code>sparse-checkout</code> feature comes in. This will allow us to only locally sync the files that we actually need for our projects. You can setup sparse checkout when you initially clone a repository or on a repository that you already have cloned. If you are switching an existing local clone of a repository to sparse checkout, skip to '''Step 3'''.
 +
 +
# '''Do steps 1 - 5 from [[#First Time Setup|First Time Setup]]'''. Or skip to '''Step 3''' if your repository is already cloned.
 +
# '''Type <code>git clone --no-checkout</code> and the url of your repository.''' (for github user Anduh, this would be <code>git clone --no-checkout https://github.com/Anduh/roll20-character-sheets.git</code>) Git is now downloading the top level files from the repository (any files that are not in a specific directory in the repository).
 +
# Figure out which directory you are going to want to track and clone locally.
 +
#* Keep in mind that these directory paths are from the repository's perspective.
 +
#* Directories with spaces in their names should be wrapped in double quotes (<code>"</code>).
 +
#* Directory names are Case Sensitive
 +
#* E.g. You want to track only files in <code>Repository/My Directory</code>, you would use it as <code>"My Directory"</code>
 +
# '''Type <code>git sparse-checkout set --sparse-index <Directory Name> <Directory Name> <...> <Last Directory Name></code>'''
 +
#* If you wanted to locally clone The files in the Storypath, rapidfire_system, and Official Savage Worlds directories, you would write <code>git sparse-checkout set --sparse-index Storypath rapidfire_system "Official Savage Worlds"</code>
 +
 +
=== Adding Directories to Sparse Checkout ===
 +
Adding directories is as simple as a single line git command.
 +
# '''Type <code>git sparse-checkout add <Directory Name> <Directory Name> <...> <Last Directory Name></code>`. Essentially the same as '''Step 4 above''', but replacing <code>set --sparse-index</code> with <code>add</code>
 +
 +
=== Removing Directories from Sparse Checkout ===
 +
Removing a directory from the list of valid sparse checkout directories cannot be done solely from the command line at this time, but it is still a relatively simple process with just 4 steps.
 +
 +
# Delete the directory that you no longer want to track
 +
# Open the <code>sparse-checkout</code> file for your repository. It is located in your repository at <code>.git/info/sparse-checkout</code>
 +
# Delete the directory name(s) from the list of directory names in the file. Make sure that each directory name is on a separate line when you are done and save the file
 +
#* Note that you can also add directories to clone locally by adding them to a new line here instead of deleting a line.
 +
# Open your command line for your repository
 +
# '''Type <code>git read-tree -mu HEAD</code> and then hit enter'''. This will tell your repository to reset what files it tracks. If this step is skipped, then the directory deletions will be tracked as a repository change.
  
 
== Commonly used commands ==
 
== Commonly used commands ==
Line 112: Line 199:
 
# When having the branch you want to reset be the active one, type <code>git reset --hard upstream/master</code>. This will force the currently active branch to reset so it is identical to the master branch of the "upstream"(the shorthand for Roll20's repository, as defined in [[#First Time Setup|First Time Setup]]). '''Warning:''' this will erase any changes you have done in this branch, so be sure to copy/save any WIP outside the repo.
 
# When having the branch you want to reset be the active one, type <code>git reset --hard upstream/master</code>. This will force the currently active branch to reset so it is identical to the master branch of the "upstream"(the shorthand for Roll20's repository, as defined in [[#First Time Setup|First Time Setup]]). '''Warning:''' this will erase any changes you have done in this branch, so be sure to copy/save any WIP outside the repo.
 
# (Optional) type <code>git push</code>. This will update the branch on your github repo, and making it easier to check if things are okay comparing to Roll20's repo on github. If there is some discrepancy between your local repo and your github repo after '''Step 1.''', you git might warn against pushing the changes to your github repo. If you're sure about performing this step, you can force the command to work by typing <code>git push '''--force'''</code>.
 
# (Optional) type <code>git push</code>. This will update the branch on your github repo, and making it easier to check if things are okay comparing to Roll20's repo on github. If there is some discrepancy between your local repo and your github repo after '''Step 1.''', you git might warn against pushing the changes to your github repo. If you're sure about performing this step, you can force the command to work by typing <code>git push '''--force'''</code>.
 +
 +
 +
If you've created the Git Aliases suggested in [[#Additional Configs]], you'd have setup the much easier-to-remember command for the same thing:<br>
 +
{{c|git fixmaster}}
  
 
===Git Status/Unstage File===
 
===Git Status/Unstage File===
Line 178: Line 269:
 
(This is an continuations directly from the previous section.) Let's assume Anduh have been working on an update to ExampleRPG, you know his branch is up to date with roll20. You want to save it for yourself on your local copy.
 
(This is an continuations directly from the previous section.) Let's assume Anduh have been working on an update to ExampleRPG, you know his branch is up to date with roll20. You want to save it for yourself on your local copy.
  
# type <code>git checkout master</code> to set active branch to your master branch.
+
'''Method A'''
# type <code>git fetch Anduh</code>. This will update refs from the remote, and informing if about changes since last time you checked, as well as new branches. This info is displayed in the CLI, and among things it shows that Anduh has a branch named "ExampleRPG-v1_5", which sounds right.
+
# '''type <code>git fetch Anduh</code>'''. This will update refs from the remote, and informing if about changes since last time you checked, as well as new branches. This info is displayed in the CLI, and among things it shows that Anduh has a branch named "ExampleRPG-v1_5", which sounds right.
# type <code>git checkout -b ExampleRPG-Anduh-v1_5</code>. This will create & switch us to this new branch, which we named in a way that reminds us that this isn't something we are working on.
+
#* ''( Doing {{code|git fetch --all}} would fetch latest info from all your remotes, not just {{code|Anduh}}.)''
# type <code>git pull Anduh ExampleRPG-v1_5</code>. This will pull all the changes from the "ExampleRPG-v1_5" branch in Anduh's remote and save it in this branch. Now, while you have the "ExampleRPG-Anduh-v1_5"-branch active, can go and see his changes to the sheet, without having it interfere with any work you have saved up.
+
# ''(optional)'' type {{code|git branch -r}} to find out the names of all remote branches.
 +
#* {{code|git branch -a}}  will show all tracked branches, local & remote.
 +
# '''type {{code|git switch ExampleRPG-Anduh-v1_5}}'''. This will checkout to a branch named {{code|ExampleRPG-Anduh-v1_5}}, and as the branch doesn't exist yet locally, and git knows about the remote branch by Anduh, it will automatically create the new branch for you, and fetch the content from the remote branch.
 +
#* You can you the {{code|-t}} parameter to automatically setup the branch to your own repo, so that if you push the branch later it works the first time as well. E.g. {{code|git switch -t ExampleRPG-Anduh-v1_5}}
 +
#* About: [https://git-scm.com/docs/git-switch git switch]
 +
 
 +
'''Method B'''
 +
 
 +
This does the same thing as '''Method A''', just using the older commands, and shows step-by-step what's happening.
 +
# '''type <code>git checkout master</code>''' to set active branch to your master branch.
 +
# '''type <code>git fetch Anduh</code>'''. This will update refs from the remote, and informing if about changes since last time you checked, as well as new branches. This info is displayed in the CLI, and among things it shows that Anduh has a branch named "ExampleRPG-v1_5", which sounds right.
 +
# '''type <code>git checkout -b ExampleRPG-Anduh-v1_5</code>'''. This will create & switch us to this new branch, which we named in a way that reminds us that this isn't something we are working on.
 +
# '''type <code>git pull Anduh ExampleRPG-v1_5</code>'''. This will pull all the changes from the "ExampleRPG-v1_5" branch in Anduh's remote and save it in this branch. Now, while you have the "ExampleRPG-Anduh-v1_5"-branch active, can go and see his changes to the sheet, without having it interfere with any work you have saved up.
  
 
'''(Optional)''' Save the branch on github
 
'''(Optional)''' Save the branch on github
::5. type <code>git pull -u origin ExampleRPG-Anduh-v1_5</code>. This will create this branch in your GitHub repo, and save all it's info there as well.
+
:4. '''type {{code|git pull -u origin ExampleRPG-Anduh-v1_5}}'''. This will create this branch in your GitHub repo, and save all it's info there as well. {{code|git pull -u}} is a shorter form of the command {{code|git pull --set-upstream}}.
  
 
==== Creating a sheet update suggestion & sending it to your collaborator ====
 
==== Creating a sheet update suggestion & sending it to your collaborator ====
Line 244: Line 347:
 
[[Category:Guides]]
 
[[Category:Guides]]
 
[[Category:Character Sheet Creation]]
 
[[Category:Character Sheet Creation]]
 +
[[Category:External Tools]]

Latest revision as of 06:00, 18 March 2024

This is a short guide on how to work with Git/GitHub locally on your computer, and how to update your fork of Roll20's GitHub Repository, using the Git Command Line(CLI).

The guide is aimed towards people who want to work with Roll20's Character Sheets and be able to interact with Roll20's Github & Git through the command line(CLI). It's recommended by those who do lots of work on character sheets and/or juggles more that one sheet at a time.

Beginner's Guide to GitHub is the other guide focusing on the GitHub part.

Contents

[edit] Why Git CLI instead of GitHub Desktop?

  • Git command line(CLI) have more guides & documentation than the GitHub Desktop/Browser
  • Using the CLI makes it easier to troubleshoot, as you clearly know what steps you took, and can see the messages or error message the CLI gives back, which you can then search for on the web or share with others
  • Learning to use Git gives you a better understanding of how Git and GitHub works. GitHub is essentially a website hosting Git, with a few extra features.

[edit] Reading this guide

  • In most places/steps, it's first written in bold the action to be done, and afterwards an explanation of what it does, and why it's done. This is to make revisiting the guide quicker when you already remember what each step means, but don't remember the exact commands/actions or their order.
  • Start with reading the guide's Glossary to understand commonly used words or phrases in the guide. If you encounter words you don't understand, google for it together with "Git" or "Github", as it is likely a term linked to them. The author of the guide has English as a second language.
  • The GitHub repository for Character Sheets are used as an example here, but it works the same with any other GitHub project you have forked, such as Roll20's API Script repo.
  • This guide is made with Linux in mind, but should work universally, if you install & setup Git on your computer with the unix-compatible option. In some places help for Windows-users are linked, while Linux-users are assumed to knowing or figure out the basics.

[edit] First Time Setup

If you've already worked with a GitHub desktop or other graphical user interface, some steps are redundant, and should be skipped if it seems to create duplicates. The setup in Step 7. will be needed for the "Update your Fork"-section if you otherwise already have a github fork and a local copy. The steps below outline how to clone the entire repository onto your computer. For most users, this is not necessary. After completing Step 6, see the Sparse Checkout section for a series of alternate setup instructions to only clone the files you need.

  1. Have your own GitHub account, and have a fork created from Roll20's repository. (When logged into GitHub, press the "fork" icon in the upper left corner of this page. It will ask you to name your fork, and my recommendation is to keep the default name, as it will keeps things simple later). Now you have your own fork of the repo, that you can do whatever you want with, but it's still only on the internet, and we want to make a local copy on your computer.
  2. Download and install Git on your computer. Atlassian Guide For Linux/Mac/Windows
  3. Go to your file manager, and navigate to a folder where you want to place your copy of the roll20 repo. The "Documents" folder is a good choice.
  4. Open up a command line prompt/interface(CLI) in this folder. Windows guide
  5. Copy the URL for your GitHub fork. Open up your browser and navigate to your Github Fork. On the left side is a green "Clone or Download" button, and if pressed, show an url that ends in ".git", which you will need in the next step. Copy it somewhere easily accessible for Step 6. (it should look something like https://github.com/YourGitHubUserName/roll20-character-sheets.git)
  6. Type git clone and the url you have from Step 5. (for github user Anduh this would look like: git clone https://github.com/Anduh/roll20-character-sheets.git). Now git is downloading and making you a local copy of your GitHub repository, and it may take some time. This will automatically set your GitHub fork as the default remote (called "origin"). When you later use commands like git push or git fetch, it will act as if you had typed git push origin or git fetch origin, interacting with your GitHub fork. More on this later.
  7. Navigate your CLI to be inside the folder created in Step 6.
  8. Type in git remote add upstream https://github.com/Roll20/roll20-character-sheets.git . This will set up Roll20's repository as an remote called upstream for your local copy, where you can pull updates from. This will be used later in the "update your Fork" section.

[edit] Additional Configs

Other configs and setup that can be nice:

Skip --set-upstream origin when pushing new branch to Github

Starting from Git 2.37.0, you can run just git push to push new branches. No more --set-upstream origin or need to setup complicated aliases. Enable with:

git config --global --add --bool push.autoSetupRemote true

Git Aliases
Make aliases to longer commands you need often or often forget. Configure new aliases with command like this:

git config --global alias.cmsg 'git commit -m'
git config --global alias.co checkout
git config --global alias.cm 'checkout master'
git config --global alias.pullr20 'pull upstream master'
git config --global alias.fixmaster 'reset --hard upstream/master'

If you do the above commands, you now have shortcuts for some common commands shown in this guide.

Example situation: You've been working on an ExampleRPG update in branch exRPG-1-40 for a few weeks, and now want to quickly submit a typo fix to the GenericQuest sheet, you'd probably do commands like:

git add .  //stage all current changes
git cmsg "ExampleRPG 1.40 - styling Skills-section WIP"  // commit changes using one of our aliases 
git cm  // checkout to master-branch
git pullr20 // pull latest changes from the roll20 repo
git co -b GenericQuest-weapontypo // create new branch for our GenericQuest changes
// do the edits you need
git add .
git cmsg "GenericQuest - fix typo in weapons"
git push // push your changes to your github, automatically creates new branch there if you've setup the config from the above section, otherwise the CLI will suggest you the command which you can copy and paste
git co exRPG-1-40 //go back to your original branch to continue on your ExampleRPG update

If you haven't setup any of the aliases nor the push.autoSetupRemote true setting, you'd have to use the full commands for each:

Commands w/o aliases or autoSetupRemote
git add .
git commit -m "ExampleRPG 1.40 - styling Skills-section WIP"
git checkout master
git pull upstream master
git checkout -b GenericQuest-weapontypo
// do the edits you need
git add .
git commit -m "GenericQuest - fix typo in weapons"
git push --set-upstream origin GenericQuest-weapontypo
git checkout exRPG-1-40

Global vs Local

You might not want to use all settings or aliases in all git repositories, so instead of using --global(user setting for any git repo), you could instead use --local to save repository-specific settings.

[edit] Sparse Checkout

The character sheet and API repositories have grown to massive sizes in the years since they were initially created. At the time of writing, the Character Sheet repository contained 1006 sheets and was several GB in size. It is very unlikely that you need, or want, all of those files on your computer's hard disk. This is where git's sparse-checkout feature comes in. This will allow us to only locally sync the files that we actually need for our projects. You can setup sparse checkout when you initially clone a repository or on a repository that you already have cloned. If you are switching an existing local clone of a repository to sparse checkout, skip to Step 3.

  1. Do steps 1 - 5 from First Time Setup. Or skip to Step 3 if your repository is already cloned.
  2. Type git clone --no-checkout and the url of your repository. (for github user Anduh, this would be git clone --no-checkout https://github.com/Anduh/roll20-character-sheets.git) Git is now downloading the top level files from the repository (any files that are not in a specific directory in the repository).
  3. Figure out which directory you are going to want to track and clone locally.
    • Keep in mind that these directory paths are from the repository's perspective.
    • Directories with spaces in their names should be wrapped in double quotes (").
    • Directory names are Case Sensitive
    • E.g. You want to track only files in Repository/My Directory, you would use it as "My Directory"
  4. Type git sparse-checkout set --sparse-index <Directory Name> <Directory Name> <...> <Last Directory Name>
    • If you wanted to locally clone The files in the Storypath, rapidfire_system, and Official Savage Worlds directories, you would write git sparse-checkout set --sparse-index Storypath rapidfire_system "Official Savage Worlds"

[edit] Adding Directories to Sparse Checkout

Adding directories is as simple as a single line git command.

  1. Type git sparse-checkout add <Directory Name> <Directory Name> <...> <Last Directory Name>`. Essentially the same as Step 4 above, but replacing set --sparse-index with add

[edit] Removing Directories from Sparse Checkout

Removing a directory from the list of valid sparse checkout directories cannot be done solely from the command line at this time, but it is still a relatively simple process with just 4 steps.

  1. Delete the directory that you no longer want to track
  2. Open the sparse-checkout file for your repository. It is located in your repository at .git/info/sparse-checkout
  3. Delete the directory name(s) from the list of directory names in the file. Make sure that each directory name is on a separate line when you are done and save the file
    • Note that you can also add directories to clone locally by adding them to a new line here instead of deleting a line.
  4. Open your command line for your repository
  5. Type git read-tree -mu HEAD and then hit enter. This will tell your repository to reset what files it tracks. If this step is skipped, then the directory deletions will be tracked as a repository change.

[edit] Commonly used commands

The central commands you will need for everyday work with your local copy, your GitHub repo & Roll20's repo.

  • git fetch - will fetch links on any changes and new branches done in your GitHub repo. If you specify a name of a remote after it, it will fetch update links from that remote. (E.g. git fetch upstream will do this for Roll20's repo, as we had set the "upstream" name to track Roll20's repo)
  • git pull - will pull any changes done in your GitHub repo from the branch with the same name(if the active branch has tracking).
  • git branch - lists all your local branches. if you type git branch name-of-branch it will create a new branch with the name
  • git checkout name-of-branch - switches which branch you have active, to the branch-name you have selected. If you write -b before the name, you create the branch before changing to it, making it redundant to first type git branch name-of-branch
  • git add . - will index all changes you have made. The "." specifies to index all changes in the repo. This index will later be used by git commit to save the changes.
  • git commit -m "ExampleRPG: write-description-here" - saves all changed registered by git add ., and saves what's written inside the double quotes as a description for your saved commit.
  • git push - will push any new commits made in the branch you're working in, to a branch on your GitHub with the same name, if you have set up an upstream for it. If you haven't, the command line will tell you this, and display an example of the command to create an upstream tracking to your repo.
  • git log- git log shows latest commits in your branch
    • git reflog shows full git history across all branches. Useful for cherry-picking and more
  • git cherry-pick pick specific commits from other branches & add them to the active branch

[edit] Workflow

When you work with git/github, you keep your "master" branch up to date with Roll20's master branch, and when you work on making changes to something, you create a new branch from your up-to-date master branch and commit changes there. This way your master branch is still intact if you want to create a more branches to work on other things/sheets, without having the work-in-progress in your other working branches interfere with this new branch. This will also mean that if you mess up something in your working branch, your master branch and other working branches are intact.

[edit] Update Your Fork

If you use GitHub Desktop or other method to work on your local copy, you can still use this section to streamline how you update your fork against Roll20's repo. This requires to have done Step 7. from First Time Setup.

  1. Open a CLI, and navigate it to be inside your repo's folder. - If you're unsure whether you have your master branch active, type git checkout master to switch to your master branch.
  2. Type git pull upstream master - This will fetch & merge any updates Roll20's main repo have done on GitHub, and save the changes to your master branch on your local copy.
  3. Type git push. - This will prompt the CLI to ask for your github username & password to approve the changes you are now trying send to your GitHub repo. When you have successfully provided your username & password, you have now managed to update both your local copy and your GitHub repo to be up to date with Roll20's main repository. (There are methods to automatically send the username and password to avoid needing to write it each time for both Windows and Linux.) If you want to update some of your working branches, in Step 1 you need to do git checkout name-of-the-branch instead.

Only the commands:

  • git checkout master
  • git pull upstream master
  • git push

[edit] Updating a work-in-progress branch

If you have some branch you have been working on for a longer time, and want to update to not lag behind the master branch too much, you can update your branch as well. Note: This has the potential to create merge conflict if changes to the same files you have been working on have been saved to Roll20's repo. Do this only if you're sure, or create a copy of your working branch as a backup in case the update goes wrong.

  1. type git checkout name-of-your-branch - This switches your active branch to the one you want to update
  2. Type git pull upstream master- This will fetch & merge any updates Roll20's main repo have done on GitHub, and save the changes to your active branch . (If the CLI doesn't give any complaints.)
  3. Type git push. This will update your copy of the branch on Github to be up to date with your local copy. Now if you look at the branch on Github, it will say it is 0 commits behind, and X commits ahead, meaning the only difference between the branch and Roll20's master branch is the changes you have worked on, and isn't lagging behind. This will make comparison of changes & creating PRs easier.

[edit] Creating a small fix and saving your progress

Situation: You have been made aware of a tiny bug for the ExampleRPG's character sheet, and know what to edit in the sheet's .html-file; someone have misspelled an attribute in the button for Strength-checks. But you don't know your way around Git/GitHub too well. This is how to do it.

  1. Open a CLI in your local repo's folder. Type git checkout master to set your master branch as the active one.
  2. You will now create a new branch. Type git branch ExampleRPG-smallfix.
  3. Type git checkout ExampleRPG-smallfix and now it will be the active branch where you can start working.
  4. Find and Open the .html-file for ExampleRPG, and edit it with any text editor you want, and then save the changes.
  5. In your CLI, type git add .. (This will update Git's tracking to note all the changes you made in your repo this far for later use. Now we have only changed one file.) (Alternatively, type git add ExampleRPG.html to only stage the changes to this file, if you think you might have made changes to other files you didn't intend.
  6. Type git status, to see that you only staged changes to files you wanted to change, i.e. only files related to this character sheet. See #Git Status/Unstage File for more details if you have staged files you don't want.
  7. Type git commit -m "ExampleRPG: Str-button fix". (This will commit all tracked changes with a message describing what you did. As there are many character sheets and people collaborating with the character sheets, it's a good idea to first mention the affected character sheet, and then a short description of what changed. This will later help you & others to read old commits and change history when searching bugs or similar)
  8. Type git push -u origin ExampleRPG-smallfix. (This will telling git it's a new branch that should be tracked to your Github, while push your changes to your GitHub. If you go and see your GitHub repo in the browser, you should see that a new branch have been created)

[edit] Submit a Pull Request to Roll20(on Github)

This is a continuation of the previous example, where you Create a PR based on a branch you have on your GitHub.

  1. Open a browser to Roll20 Github Repo, and and if you recently updated one of your branches, there should be a yellow notification at the top mentioning this, and a button to to create a Pull Request. Press this button. (If this doesn't appear, navigate to your own Github repo's page, where you find a button saying "Create Pull Request". Before you press it, you can from the dropdown beside it select the name of the branch you want to make a PR from, and it will be automatically set the correct one. If you don't, you need to change the dropdown when you are on the page in the next step)
  2. Change the title of the Pull Request to clearly indicate what it is about. We'll change the name to "[ExampleRPG] Str button fix". In the Description section, we write "This fixes an attribute name typo in the Str button., and leave no other comment as this was a small change.(Now our PR will have the same naming format as PRs submitted by other people, and have a short description of what what it does. This will make it easier for others to get a quick & self-explanatory overview of what the PR is about. In this example the description & title-change of the PR might seem a bit redundant, but will be much more useful when you make lot of changes, or of the PR consists of several commits)
  3. Now the Pull Request is submitted, and you see the description looks like. At the end of the description, there is a list of checkboxes that needs to be checked, so that Roll20 have easier to know what the PR is about. We check the two first boxes, as we mention the character sheet's name in the title, and this is a bug fix.

Now the pull request is submitted, and will eventually be reviewed by Roll20(Review happen once a week, on Mondays). They may comment on it and request some clarifications or changes, but in this case they will likely approve and merge it without problems. When the pull request turns from green to purple, Roll20 have merged the changes into the main repo.


[edit] Working with multiple branches

If you work on updates to two different sheets, the smart thing to do is to have separate branches for each update.

Let's say you have recently been working on creating a ship page for the MegaSmashRPG character sheet, but also want to start working on a visual update to ExampleRPG. You don't quite remember if you committed all your changes for MegaSmashRPG, and don't remember what branch you have active.

  1. Open your CLI in the character sheet folder, and type git branch. It shows the list of branches you have on your local repo, and shows an asterisk next to the branch that's active, and in this case it shows "MegaSmashShipupdate".
  2. type git add .. This indexes all your un-tracked changes if you this command wasn't the last thing you did last time. If the CLI say anything, you can skip step 3 and 4.
  3. type git commit -m "MegaSmashRPG: Ship update". This will save all this last change you did, and give the commit a name that tells what the changes was related to, even if you don't remember the details. This is still better that a commit message that says "last changes", as it won't later tell anyone any context on what it contains.
  4. (Optional) type git push. If you had previously already saved this branch on Github with git push -u origin MegaSmashShipupdate, this will update your github with the changes from your computer. Now others can see how long you current progress since you updated your GitHub the last time. This will also save your progress on the internet for you in case a mimic destroys and eats your computer.
  5. type git checkout master. You have now changed your active branch to master which is the "clean" branch we want to start form if we want to work on something new.
  6. type git checkout -b ExampleRPG-visual. This will create a fresh new branch based on your master branch, with a name that makes sense to you and what you intended to work on. if you don't first switch to the master branch before performing this step, you would also copy all your work on MegaSmashRPG to this branch, which will cause you trouble when you try submit your next PR.
  7. Open up the files for ExampleRPG and work on the changes you want. Remember to save often, in case a goblin comes and turns of your computer while you're working. (Let's say you worked on improving how the inventory section looked like, and adjusted some colors.)
  8. type git add . This indexes all your un-tracked changes you have done since you last used the command.
  9. type git commit -m "ExampleRPG: Visual update on inventory, small color adjustments". Now we have commit all our changes, together with a commit message that describes what we did.
  10. (Optional) type git push -u origin ExampleRPG-visual. This will update your github to have the new branch you just created, tell this branch on your computer to push/pull/fetch things from there in the future, and upload all your changes. When you later work in this branch, you can type just git push and it now knows where to send things.
  11. (Optional) git checkout master. Now your have set your active branch to "master", which means next time when you decide to work/check on things, you know you shouldn't have any uncommitted changes laying around. It will make for an easier starting point next time around.



[edit] Fixing your master branch

Sometimes you might do something that result in you making changes to your master branch, which could cause troubles down the line. One way to revert these changes to your branch is by performing the git reset command and telling git to reset your branch to how Roll20's master branch currently looks like.

  1. When having the branch you want to reset be the active one, type git reset --hard upstream/master. This will force the currently active branch to reset so it is identical to the master branch of the "upstream"(the shorthand for Roll20's repository, as defined in First Time Setup). Warning: this will erase any changes you have done in this branch, so be sure to copy/save any WIP outside the repo.
  2. (Optional) type git push. This will update the branch on your github repo, and making it easier to check if things are okay comparing to Roll20's repo on github. If there is some discrepancy between your local repo and your github repo after Step 1., you git might warn against pushing the changes to your github repo. If you're sure about performing this step, you can force the command to work by typing git push --force.


If you've created the Git Aliases suggested in #Additional Configs, you'd have setup the much easier-to-remember command for the same thing:
git fixmaster

[edit] Git Status/Unstage File

If you accidentally staged file-changes you don't want to commit, you can use git reset to unstage the files you don't want to change in your next commit.

1. type git status in the CLI, and you will be shown all the files that have been staged.

In this example, we've been working on an update to the Stargate character sheet, and realize we have accidentally made some edits to ExampleRPG, and even staged one of the files.

On branch stargateNPC-june
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   ../Stargate-RPG/src/pug/core.pug
	new file:   ../Stargate-RPG/src/pug/variables.pug
	modified:   ../Stargate-RPG/stargate.pug
	modified:   ../ExempleRPG/ExempleRPG.html

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   ../ExempleRPG/ExempleRPG.css

2. navigate your CLI to the folder where the ExempleRPG.html file is located, and git reset ExempleRPG.html. This should now have unstaged the file. (Alternatively, from the root folder for roll20-character-sheets, do git reset /ExempleRPG/ExempleRPG.html)
3. type git status to see what files are staged, and we should now see that only the files we want are staged, so we can go ahead & commit the changes as normal.

On branch stargateNPC-june
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   ../Stargate-RPG/src/pug/core.pug
	new file:   ../Stargate-RPG/src/pug/variables.pug
	modified:   ../Stargate-RPG/stargate.pug

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   ../ExempleRPG/ExempleRPG.css
	modified:   ../ExempleRPG/ExempleRPG.html

4. when we want to change active branch back to master(or other branch), git will mention the unstaged changes, and stop you from checking out from the branch. If you don't want to keep the changes at all, you can do git checkout -f master, which will discard these changes while changing active branch.

[edit] Clean up Commits

If you end up having tons of commits, or want to rewrite the commit message for the latest one, you might want to consider squashing them.

Combining last two commits: Example

Let's say we are working on a small update to the ExampleRPG sheet, and we have saved our progress in two commits so far. But we realize now that we left very vague commit messages for both, "fix inititive" and "ExampleRPG fix". We feel the update is good enough, but want to replace the vauge messages with one that clearly states which sheet was affected, the sheet version, and a short version of what was done.

  1. Type git reset --soft HEAD~2. This will remove the last two commits, but keep the changes from them, like if you only had saved the progress with git add . but not yet committed the changes.
  2. Type git commit -m "ExampleRPG v.1.61: Fixed init bug & minor visual updates". This will become the new commit message for what we done, and it's now clear from the message alone what was done without having to check the actual changes.

After this we continue as normal.

[edit] How to Collaborate

If you want to collaborate with someone to create a single PR for both of your works, you can set up remote tracking to your collaborators GitHub so you can pull their latest work to your computer without having to wait for them to be merged to Roll20's repo first.

  1. Find/get a link to your collaborator's Github repo. (check Step 6, First Time Setup). If they don't have a fork of the Roll20 repo, they must first create one. (For example, if your collaborator is Anduh, the url would be:https://github.com/Anduh/roll20-character-sheets.git)
  2. Open up the CLI in your working folder, and type git remote add name-you-want-for-this-remote https://github.com/name-of-your-collborator/name-of-their-repo.git. (For example, if your collaborator is "Anduh", it would be smart to name the remote simply that. the command would then look like git add remote Anduh https://github.com/Anduh/roll20-character-sheets.git)

Now you have added the other person's repo as a remote, which makes it easier to copy any work they have going on by simply referring to the nickname you've give the remote, rather than having to use the full url of the repo.

[edit] Create a copy of someone's branch

(This is an continuations directly from the previous section.) Let's assume Anduh have been working on an update to ExampleRPG, you know his branch is up to date with roll20. You want to save it for yourself on your local copy.

Method A

  1. type git fetch Anduh. This will update refs from the remote, and informing if about changes since last time you checked, as well as new branches. This info is displayed in the CLI, and among things it shows that Anduh has a branch named "ExampleRPG-v1_5", which sounds right.
    • ( Doing git fetch --all would fetch latest info from all your remotes, not just Anduh.)
  2. (optional) type git branch -r to find out the names of all remote branches.
    • git branch -a will show all tracked branches, local & remote.
  3. type git switch ExampleRPG-Anduh-v1_5. This will checkout to a branch named ExampleRPG-Anduh-v1_5, and as the branch doesn't exist yet locally, and git knows about the remote branch by Anduh, it will automatically create the new branch for you, and fetch the content from the remote branch.
    • You can you the -t parameter to automatically setup the branch to your own repo, so that if you push the branch later it works the first time as well. E.g. git switch -t ExampleRPG-Anduh-v1_5
    • About: git switch

Method B

This does the same thing as Method A, just using the older commands, and shows step-by-step what's happening.

  1. type git checkout master to set active branch to your master branch.
  2. type git fetch Anduh. This will update refs from the remote, and informing if about changes since last time you checked, as well as new branches. This info is displayed in the CLI, and among things it shows that Anduh has a branch named "ExampleRPG-v1_5", which sounds right.
  3. type git checkout -b ExampleRPG-Anduh-v1_5. This will create & switch us to this new branch, which we named in a way that reminds us that this isn't something we are working on.
  4. type git pull Anduh ExampleRPG-v1_5. This will pull all the changes from the "ExampleRPG-v1_5" branch in Anduh's remote and save it in this branch. Now, while you have the "ExampleRPG-Anduh-v1_5"-branch active, can go and see his changes to the sheet, without having it interfere with any work you have saved up.

(Optional) Save the branch on github

4. type git pull -u origin ExampleRPG-Anduh-v1_5. This will create this branch in your GitHub repo, and save all it's info there as well. git pull -u is a shorter form of the command git pull --set-upstream.

[edit] Creating a sheet update suggestion & sending it to your collaborator

Continuing from the previous section where we created the ExampleRPG-v1_5-branch, taken from Anduh's Github repo, we now could start working on an suggested update on their sheet/update directly, instead of going through Roll20's official repo. This means two ore more people could collaborate on creating a larger sheet update among themselves by sending PRs back and forth, and then later would only one coherent PR be submitted to Roll20's repo, that contains work of the collaborators.

Let's assume (from the previous section) that the v.1.5 update for "ExampleRPG" that Anduh have been working on his ExampleRPG-v1_5-branch have miss-spelt a new attribute name that the update would introduce, and you want to create a quick fix that he could merge into his work.

  1. Open a CLI in your local repo's folder. Type git checkout ExampleRPG-Anduh-v1_5. This sets the active branch to branch containing the current version of Anduh's v.1.5 update that you have on your local repo.
  2. type git checkout -b ExampleRPG-Anduh-v1_5_attrfix. This will create us a new working branch based on ExampleRPG-Anduh-v1_5, and changing it to be our active branch. If any mistakes are made here, we can always go back to and create a new branch from ExampleRPG-Anduh-v1_5 without having to download it again.
  3. Open the files for ExampleRPG, make the changes needed, and then save.
  4. Type git add .. (Updates Git's tracking so all file changes will be committed with the next commit.)
  5. Type git commit -m "ExampleRPG v.1.5: correct typo in attr name perception-mod ". (Commits the changes & leaves a commit message clearly stating what was done)
  6. Type git push -u origin ExampleRPG-Anduh-v1_5_attrfix. (This will create this branch on your github repo)
  7. On GitHub, navigate to your github repository, and then select and go to your ExampleRPG-Anduh-v1_5_attrfix-branch. Press on the "Create Pull Request"-button.
  8. This will by default suggest to make a PR to "base repository: Roll20/roll20-character-sheets", "base:master" We will change this destination to instead be "base repository: Anduh/roll20-character-sheets" and "base:ExampleRPG-Anduh-v1_5".
  9. GitHub might take a few seconds to update, but it should now display the changes between the branches, which should only be one commit, the one we named "ExampleRPG v.1.5: correct typo in attr name perception-mod ". If everything looks good, Update the PR title and description if needed and then press submit.

Now your fix to the ExampleRPG's v.1.5 have been sent to Anduh, and he can then on GitHub merge your changes, update his local branch, and when eventually submitting the update to Roll20, your commit will be included in it.

[edit] Updating your branch when your collaborator have updated theirs

Updating a work-in-progress branch is very similar to how we'd update our local copy/branch of of our collaborators work.

Continuing form the previous section, let's assume Anduh merged the attribute fix into his ExampleRPG-Anduh-v1_5-branch as well as some other changes, so now we want to update our copy of ExampleRPG-Anduh-v1_5 so that we see the current state of the sheet, as well as be able to submit more updates without trouble.(If you don't update your local version of the branch before making more changes and them submitting them, it will likely result in merge conflicts due to your files not being up-to-date)

  1. Type git checkout ExampleRPG-Anduh-v1_5. (This switches your active branch to the one you want to update)
  2. Type git pull Anduh ExampleRPG-Anduh-v1_5 - This will fetch & merge any updates from Anduh's repo for the branch named "ExampleRPG-Anduh-v1_5", and save the changes to your active branch. (If the CLI doesn't give any complaints.)
  3. (optional) Type git push. This will update the branch on your GitHub as well.


It's best to perform this step before each time you start working on a new change, to ensure you stay up-to-date with your files. You can now do Creating a sheet update suggestion & sending it to your collaborator again without issue.

[edit] Glossary

  • "CLI": short for "Command Line Interface"
  • "your local repo/copy/working folder": In this context I refer to the copy of your GitHub repo you have saved on your computer with git clone.
  • "your Github Repo/fork": Refers to the GitHub repo you have forked from Roll20 repo. It's the repo you "local copy" interacts and mirrors with when you do most things
  • "repo": short for a Git/GitHub "repository". A Git repository is a virtual storage of your project. It allows you to save versions of your code, which you can access when needed.
  • "PR": Pull Request, a GitHub concept. What Are GitHub Pull Requests?
  • "ref/refs": reference, references. git-specific meaning
  • "origin": Is the original source your local copy was cloned from. In this guide, it refers to your GitHub fork/repo. When you perform most git commands that sends or receives info, it will assume you refer to this "origin" remote, rather than someone other remote you have defined, such as "upstream"
  • "upstream": In this guide, it refers specifically to Roll20's remote repo, which we have defined as being named "upstream". For more, see Git Forks & Upstreams
  • ExampleRPG: Not a real game or character sheet(yet?), but serves as the repeated example in the guide for clarity.

[edit] Related Pages

[edit] See Also