1 What is Git?

Git is a distributed version control system which is generally used in conjunction with, but is not the same as GitHub, which is a software used for versioning, code sharing, and publishing. Essentially, Git helps you keep track of changes to files within a project or project folder in snapshots, while GitHub provides a centralized location to store and share information. We will talk more about GitHub in our next exercise. For now we will focus on some of the primary commands to help with versioning control using Git.

1.1 Getting Started

Git is an open-source software that can be installed on Window, Mac, or Linux consoles. Fortunately, Git has already been installed on the lab computers, but if you are using your personal laptop take this time to follow the link to the proper version of the software, download, and install it on your computer. Once installed, navigate to the Git Bash terminal or other terminal application on your computer. On Windows you can access this via the Start Menu:

windows start menu highlighting the git bash terminal

Git Bash is a command line terminal with BASH (bourne again shell) emulation for PC. Its appearance is similar to other terminals you may have interfaced with previously. On a Mac you can use spotlight to locate the terminal window for that operating system or to avoid directory issues, navigate to the appropriate folder and select “new terminal at folder” from the menu.

git bash terminal

One of the first steps to setting up Git is identifing who is actually responsible for the changes to the content being edited. In order to set this up you can use the following two lines of code:

git config --global user.name "INSERT YOUR NAME HERE"

and

git config --global user.email "INSERT YOUR EMAIL HERE"

You can use git config --list if you need to review the information you provided with the other git config commands.

If you plan to use Git in combination with a code sharing or publishing service like:

BitBucket GitHub GitKraken GitLab SourceForge


you may be able to interface with programs like RStudio or Anaconda for version control. In the next exercise we will use RStudio for version control and continue using that same method for the remainder of the course.

1.1.1 Git Commands

Although we can git by with using a program like RStudio because of its built-in version control, you can use Git on your machine to create a local git repository. A repository is like a folder for your project or project folder. Your project repository contains all of your project files and stores the revision history for each file. Repositories and be owned or shared with others utilizing that same computer or network folder. In the case of a cloud-based repository, that information can be shared by individuals on different networks. For now, we will be working locally to create a git repository.

To start, please create a folder in your student folder in the Z: Drive titled 7-Git.

Tip: various applications dislike the utilization of spaces in your directory path. It’s good to get in the habit of replacing them with underscores or dashes.

Now we need to use Git Bash or the terminal window to provide some actions via command line. The first command will be to change the working directory for your git repository.

cd z:/Students/YOUR NAME/7-Git

or in the terminal window

cd \Students\YOUR NAME\7-Git

This will direct Git to identify the appropriate folder to initiate the repository. Initializing the folder lets Git know it needs to be tracked for changes. This can be done using the following command:

git init

The terminal window should respond with “Initialized empty Git repository in Z:/Students/YOUR NAME/7-Git/.git/” and show the directory as /z/Students/YOUR NAME/7-Git (master)

If you navigate to your student folder on the Z: Drive you should now see a new folder .git that was created. Within that folder there should be a number of other folder and files. If you want to see information regarding this folder you can type:

git status

Git will then report the level of the project (branch master), whether there are current commits (No commits yet) and state there is “nothing to commit (create/copy files and use”git add" to track)" information within the project folder. Now it is time to begin adding files and/or folders to be tracked by Git. To do this you can simply drag and drop files from a previous exercise or from a new project. So lets start by adding the information from your 1-Markdown (data, scripts, and html) to the new 7-Git folder you created above. You can use the ls command in bash or dir in the terminal window to see those files in the new folder.

Once you have files added to the folder you can choose to track the changes on an individual file using:

git add <file name>

Alternatively you can mark every file using the following command:

git add . 

For this example, go ahead and use the command to add all of the added files and folders. Once you have added these files, run the git status command again. This should provide you with details regarding the number of files marked in the repository. This is also called staging files. You will see this terminology when we begin to use Git and GitHub with RStudio.

If you want to remove a file once it has been stagged you can use the following command:

git rm --cached <file name>

In order to finalize this repository, you must commit (sort of the Git term for save) these files. To do that, you must also add a commit message. This message should be concise and detail the changes or additions that are being made. For example, you could say “adding rmd” or “updated r script” or something similar to that. Use the following command to commit the changes and add your own commit message.

git commit -m "Place the required commit message here"

When we begin to utilize GitHub for version control we will use the push command to add those changes to any code sharing site. However, for this example we will not need the push command.

git push

To test your understanding of the process above, create a new text file in the directory called test.txt and try repeating the steps above using the git add test.txt command. Then commit the file using an apporpriate commit message. When finished use the following command:

git log

What does this tell you?

1.1.2 Git Ignore

If you don’t want to commit all of the files in a given project you can create a .gitignore file. This is a simple text file that creates rules for all users of the project to ignore committing particular files or folders. This file should be staged and committed to the repository so it is globally available for all users.

To create the .gitignore file, type the following command:

touch .gitignore

or in the terminal window

type nul > .gitignore

Once you have created the file, navigate to your student drive and right click on the file to open with a text editor such as Code Writer, NotePad, TextPad, Visual Studio Code, WordPad, etc. The same text commenting syntax that operates in programs like R also work here. So if you include a # this will be treated as a comment, blank lines match no information so are not run and can be used as separators for legibility, etc.

In the .gitignore file, I generally like to begin with a comment regarding what needs to be ignored. The following is a simple example:

#Ignore these folders
images/
examples/

#Ignore these file types
*.cvs
*.txt
*.docx
*.xlsx

#Ignore these files
test_nb.Rmd
.Rhistory

Since the .gitignore file is stored in your repository, you don’t need to provide the entire path to specific files or folders. Git and GitHub will search the entire repository and list of commits to ignore the files identified in the .gitignore document. Be sure to add and commit the file once it has been updated.

1.2 Final Thoughts

At this point you have initalized a folder, stagged files, and committed them. Generally speaking, we will repeat all of these steps within Rstudio in the next exercise. However, Git can be used locally, without a cloud-based repository, and is a great way to manage long-term projects. Even if you aren’t using GitHub, you should probably go ahead and create an account, they provide a summary cheatsheet for commonly used Git commands. This can be helpful if you forget some of the basic instructions for creating repositories, staging files, commit and commenting, or just to git by.

2 Your Turn!

Using the skills you acquired above, create a git repository for Exercise 2 titled 2-GLM. In this repository include the markdown document, html file, and the R project files. Additionally, create a .gitignore file to exclude any image files you created, the excel dataset, and any ancillary folders.

2.1 Additional Help

After creating this exercise I stumbled onto this YouTube video, Learn Git In 15 Minutes, from Colt Steele. This video provides a fantastic visusal, step-by-step look at several Git commands. If you run into issues moving forward this video can likely answer your question, and remember, Google is your friend.

LS0tDQp0aXRsZTogIkdpdCBCYXNpY3MgPGJyPjxzbWFsbD5BZHZhbmNlZCBEYXRhIEFuYWx5dGljczwvc21hbGw+PC9icj4iDQphdXRob3I6ICJCSU9MIDU2NjAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgcm93cy5wcmludDogMTANCiAgICB0aGVtZTogY29zbW8NCiAgICBoaWdobGlnaHQ6IGJyZWV6ZWRhcmsNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KICBtb2RlOiBnZm0NCi0tLQ0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDQwcHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KPC9zdHlsZT4NCg0KIyBXaGF0IGlzIEdpdD8NCjxhIGhyZWY9Imh0dHBzOi8vZ2l0LXNjbS5jb20vIiB0YXJnZXQ9Il9ibGFuayI+R2l0PC9hPiBpcyBhIGRpc3RyaWJ1dGVkIHZlcnNpb24gY29udHJvbCBzeXN0ZW0gd2hpY2ggaXMgZ2VuZXJhbGx5IHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCwgYnV0IGlzIG5vdCB0aGUgc2FtZSBhcyA8YSBocmVmPSJodHRwczovL3d3dy5naXRodWIuY29tLyIgdGFyZ2V0PSJfYmxhbmsiPkdpdEh1YjwvYT4sIHdoaWNoIGlzIGEgc29mdHdhcmUgdXNlZCBmb3IgdmVyc2lvbmluZywgY29kZSBzaGFyaW5nLCBhbmQgcHVibGlzaGluZy4gRXNzZW50aWFsbHksICoqR2l0KiogaGVscHMgeW91IGtlZXAgdHJhY2sgb2YgY2hhbmdlcyB0byBmaWxlcyB3aXRoaW4gYSBwcm9qZWN0IG9yIHByb2plY3QgZm9sZGVyIGluIHNuYXBzaG90cywgd2hpbGUgKipHaXRIdWIqKiBwcm92aWRlcyBhIGNlbnRyYWxpemVkIGxvY2F0aW9uIHRvIHN0b3JlIGFuZCBzaGFyZSBpbmZvcm1hdGlvbi4gV2Ugd2lsbCB0YWxrIG1vcmUgYWJvdXQgR2l0SHViIGluIG91ciBuZXh0IGV4ZXJjaXNlLiBGb3Igbm93IHdlIHdpbGwgZm9jdXMgb24gc29tZSBvZiB0aGUgcHJpbWFyeSBjb21tYW5kcyB0byBoZWxwIHdpdGggdmVyc2lvbmluZyBjb250cm9sIHVzaW5nIEdpdC4NCg0KIyMgR2V0dGluZyBTdGFydGVkDQoNCioqR2l0KiogaXMgYW4gb3Blbi1zb3VyY2Ugc29mdHdhcmUgdGhhdCBjYW4gYmUgaW5zdGFsbGVkIG9uIFdpbmRvdywgTWFjLCBvciBMaW51eCBjb25zb2xlcy4gRm9ydHVuYXRlbHksICoqR2l0KiogaGFzIGFscmVhZHkgYmVlbiBpbnN0YWxsZWQgb24gdGhlIGxhYiBjb21wdXRlcnMsIGJ1dCBpZiB5b3UgYXJlIHVzaW5nIHlvdXIgcGVyc29uYWwgbGFwdG9wIHRha2UgdGhpcyB0aW1lIHRvIGZvbGxvdyB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9naXQtc2NtLmNvbS9kb3dubG9hZHMiIHRhcmdldD0iX2JsYW5rIj5saW5rPC9hPiB0byB0aGUgcHJvcGVyIHZlcnNpb24gb2YgdGhlIHNvZnR3YXJlLCBkb3dubG9hZCwgYW5kIGluc3RhbGwgaXQgb24geW91ciBjb21wdXRlci4gT25jZSBpbnN0YWxsZWQsIG5hdmlnYXRlIHRvIHRoZSAqR2l0IEJhc2gqIHRlcm1pbmFsIG9yIG90aGVyIHRlcm1pbmFsIGFwcGxpY2F0aW9uIG9uIHlvdXIgY29tcHV0ZXIuIE9uICpXaW5kb3dzKiB5b3UgY2FuIGFjY2VzcyB0aGlzIHZpYSB0aGUgPHU+U3RhcnQgTWVudTwvdT46DQoNCjxwIGFsaWduPSJjZW50ZXIiPg0KIVsqd2luZG93cyBzdGFydCBtZW51IGhpZ2hsaWdodGluZyB0aGUgZ2l0IGJhc2ggdGVybWluYWwqXShDOi9Vc2Vycy9nZW50cnljL0dvb2dsZSBEcml2ZS9BUFNVL0NvdXJzZXMvQklPTCA1NzAwIEFkdmFuY2VkIERhdGEgQW5hbHl0aWNzXEV4ZXJjaXNlXzcvR2l0QmFzaFBDLmpwZyAiV2luZG93cyBTdGFydCBNZW51IikNCjwvcD4NCg0KKkdpdCBCYXNoKiBpcyBhIGNvbW1hbmQgbGluZSB0ZXJtaW5hbCB3aXRoIEJBU0ggKGJvdXJuZSBhZ2FpbiBzaGVsbCkgZW11bGF0aW9uIGZvciBQQy4gSXRzIGFwcGVhcmFuY2UgaXMgc2ltaWxhciB0byBvdGhlciB0ZXJtaW5hbHMgeW91IG1heSBoYXZlIGludGVyZmFjZWQgd2l0aCBwcmV2aW91c2x5LiBPbiBhICpNYWMqIHlvdSBjYW4gdXNlIHNwb3RsaWdodCB0byBsb2NhdGUgdGhlIHRlcm1pbmFsIHdpbmRvdyBmb3IgdGhhdCBvcGVyYXRpbmcgc3lzdGVtIG9yIHRvIGF2b2lkIGRpcmVjdG9yeSBpc3N1ZXMsIG5hdmlnYXRlIHRvIHRoZSBhcHByb3ByaWF0ZSBmb2xkZXIgYW5kIHNlbGVjdCAqIm5ldyB0ZXJtaW5hbCBhdCBmb2xkZXIiKiBmcm9tIHRoZSBtZW51Lg0KDQo8cCBhbGlnbj0iY2VudGVyIj4NCiFbKmdpdCBiYXNoIHRlcm1pbmFsKl0oQzovVXNlcnMvZ2VudHJ5Yy9Hb29nbGUgRHJpdmUvQVBTVS9Db3Vyc2VzL0JJT0wgNTcwMCBBZHZhbmNlZCBEYXRhIEFuYWx5dGljcy9FeGVyY2lzZV83L0dpdEJhc2hUZXJtaW5hbC5qcGcgIkdpdCBCYXNoIFRlcm1pbmFsIikNCjwvcD4NCg0KT25lIG9mIHRoZSBmaXJzdCBzdGVwcyB0byBzZXR0aW5nIHVwICoqR2l0KiogaXMgaWRlbnRpZmluZyB3aG8gaXMgYWN0dWFsbHkgcmVzcG9uc2libGUgZm9yIHRoZSBjaGFuZ2VzIHRvIHRoZSBjb250ZW50IGJlaW5nIGVkaXRlZC4gSW4gb3JkZXIgdG8gc2V0IHRoaXMgdXAgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyB0d28gbGluZXMgb2YgY29kZToNCg0KYGBge2Jhc2h9DQpnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIubmFtZSAiSU5TRVJUIFlPVVIgTkFNRSBIRVJFIg0KYGBgDQoNCmFuZA0KDQpgYGB7YmFzaH0NCmdpdCBjb25maWcgLS1nbG9iYWwgdXNlci5lbWFpbCAiSU5TRVJUIFlPVVIgRU1BSUwgSEVSRSINCmBgYA0KDQpZb3UgY2FuIHVzZSBgYGBnaXQgY29uZmlnIC0tbGlzdGBgYCBpZiB5b3UgbmVlZCB0byByZXZpZXcgdGhlIGluZm9ybWF0aW9uIHlvdSBwcm92aWRlZCB3aXRoIHRoZSBvdGhlciAqZ2l0IGNvbmZpZyogY29tbWFuZHMuDQoNCklmIHlvdSBwbGFuIHRvIHVzZSAqKkdpdCoqIGluIGNvbWJpbmF0aW9uIHdpdGggYSBjb2RlIHNoYXJpbmcgb3IgcHVibGlzaGluZyBzZXJ2aWNlIGxpa2U6PGJyPjwvYnI+DQo8YnI+PC9icj4NCjxwIGFsaWduPSJjZW50ZXIiPg0KPGEgaHJlZj0iaHR0cHM6Ly9iaXRidWNrZXQub3JnL3Byb2R1Y3QiPjxpbWcgc3JjPSJDOlxcVXNlcnNcXGdlbnRyeWNcXEdvb2dsZSBEcml2ZVxcQVBTVVxcQ291cnNlc1xcQklPTCA1NzAwIEFkdmFuY2VkIERhdGEgQW5hbHl0aWNzXFxFeGVyY2lzZV83XFxCaXRCdWNrZXQucG5nIiBzdHlsZT0id2lkdGg6MTUwcHg7IGhlaWdodDoxNTBweCIgdGl0bGU9IkJpdEJ1Y2tldCIgYWx0PSJCaXRCdWNrZXQiPjwvYT4gPGEgaHJlZj0iaHR0cHM6Ly93d3cuZ2l0aHViLmNvbS8iPjxpbWcgc3JjPSJDOlxcVXNlcnNcXGdlbnRyeWNcXEdvb2dsZSBEcml2ZVxcQVBTVVxcQ291cnNlc1xcQklPTCA1NzAwIEFkdmFuY2VkIERhdGEgQW5hbHl0aWNzXFxFeGVyY2lzZV83XFxHaXRIdWIucG5nIiBzdHlsZT0id2lkdGg6MTUwcHg7IGhlaWdodDoxNTBweCIgdGl0bGU9IkdpdEh1YiIgYWx0PSJHaXRIdWIiPjwvYT4gPGEgaHJlZj0iaHR0cHM6Ly93d3cuZ2l0a3Jha2VuLmNvbS8iPjxpbWcgc3JjPSJDOlxcVXNlcnNcXGdlbnRyeWNcXEdvb2dsZSBEcml2ZVxcQVBTVVxcQ291cnNlc1xcQklPTCA1NzAwIEFkdmFuY2VkIERhdGEgQW5hbHl0aWNzXFxFeGVyY2lzZV83XFxHaXRLcmFrZW4ucG5nIiBzdHlsZT0id2lkdGg6MTc2cHg7IGhlaWdodDoxNTBweCIgdGl0bGU9IkdpdEtyYWtlbiIgYWx0PSJHaXRLcmFrZW4iPjwvYT4gPGEgaHJlZj0iaHR0cHM6Ly9hYm91dC5naXRsYWIuY29tLyI+PGltZyBzcmM9IkM6XFxVc2Vyc1xcZ2VudHJ5Y1xcR29vZ2xlIERyaXZlXFxBUFNVXFxDb3Vyc2VzXFxCSU9MIDU3MDAgQWR2YW5jZWQgRGF0YSBBbmFseXRpY3NcXEV4ZXJjaXNlXzdcXEdpdExhYi5wbmciIHN0eWxlPSJ3aWR0aDoxNjRweDsgaGVpZ2h0OjE1MHB4IiB0aXRsZT0iR2l0TGFiIiBhbHQ9IkdpdExhYiI+PC9hPiA8YSBocmVmPSJodHRwczovL3NvdXJjZWZvcmdlLm5ldC8iPjxpbWcgc3JjPSJDOlxcVXNlcnNcXGdlbnRyeWNcXEdvb2dsZSBEcml2ZVxcQVBTVVxcQ291cnNlc1xcQklPTCA1NzAwIEFkdmFuY2VkIERhdGEgQW5hbHl0aWNzXFxFeGVyY2lzZV83XFxTb3VyY2VGb3JnZS5wbmciIHN0eWxlPSJ3aWR0aDoxNTBweDsgaGVpZ2h0OjE1MHB4IiB0aXRsZT0iU291cmNlRm9yZ2UiIGFsdD0iU291cmNlRm9yZ2UiPjwvYT4gDQo8L3A+DQo8YnI+PC9icj4NCnlvdSBtYXkgYmUgYWJsZSB0byBpbnRlcmZhY2Ugd2l0aCBwcm9ncmFtcyBsaWtlIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnJzdHVkaW8uY29tLyIgdGFyZ2V0PSJfYmxhbmsiPlJTdHVkaW88L2E+IG9yIDxhIGhyZWY9Imh0dHBzOi8vd3d3LmFuYWNvbmRhLmNvbS9kaXN0cmlidXRpb24vIiB0YXJnZXQ9Il9ibGFuayI+QW5hY29uZGE8L2E+IGZvciB2ZXJzaW9uIGNvbnRyb2wuIEluIHRoZSBuZXh0IGV4ZXJjaXNlIHdlIHdpbGwgdXNlIFJTdHVkaW8gZm9yIHZlcnNpb24gY29udHJvbCBhbmQgY29udGludWUgdXNpbmcgdGhhdCBzYW1lIG1ldGhvZCBmb3IgdGhlIHJlbWFpbmRlciBvZiB0aGUgY291cnNlLg0KDQojIyMgR2l0IENvbW1hbmRzDQoNCkFsdGhvdWdoIHdlIGNhbiBbZ2l0XShodHRwczovL3d3dy5tZXJyaWFtLXdlYnN0ZXIuY29tL2RpY3Rpb25hcnkvcHVuKSBieSB3aXRoIHVzaW5nIGEgcHJvZ3JhbSBsaWtlIFJTdHVkaW8gYmVjYXVzZSBvZiBpdHMgYnVpbHQtaW4gdmVyc2lvbiBjb250cm9sLCB5b3UgY2FuIHVzZSBHaXQgb24geW91ciBtYWNoaW5lIHRvIGNyZWF0ZSBhIGxvY2FsICpnaXQgcmVwb3NpdG9yeSouIEEgcmVwb3NpdG9yeSBpcyBsaWtlIGEgZm9sZGVyIGZvciB5b3VyIHByb2plY3Qgb3IgcHJvamVjdCBmb2xkZXIuIFlvdXIgcHJvamVjdCByZXBvc2l0b3J5IGNvbnRhaW5zIGFsbCBvZiB5b3VyIHByb2plY3QgZmlsZXMgYW5kIHN0b3JlcyB0aGUgcmV2aXNpb24gaGlzdG9yeSBmb3IgZWFjaCBmaWxlLiBSZXBvc2l0b3JpZXMgYW5kIGJlIG93bmVkIG9yIHNoYXJlZCB3aXRoIG90aGVycyB1dGlsaXppbmcgdGhhdCBzYW1lIGNvbXB1dGVyIG9yIG5ldHdvcmsgZm9sZGVyLiBJbiB0aGUgY2FzZSBvZiBhIGNsb3VkLWJhc2VkIHJlcG9zaXRvcnksIHRoYXQgaW5mb3JtYXRpb24gY2FuIGJlIHNoYXJlZCBieSBpbmRpdmlkdWFscyBvbiBkaWZmZXJlbnQgbmV0d29ya3MuIEZvciBub3csIHdlIHdpbGwgYmUgd29ya2luZyBsb2NhbGx5IHRvIGNyZWF0ZSBhIGdpdCByZXBvc2l0b3J5LiANCg0KVG8gc3RhcnQsIHBsZWFzZSBjcmVhdGUgYSBmb2xkZXIgaW4geW91ciBzdHVkZW50IGZvbGRlciBpbiB0aGUgPHU+WjogRHJpdmU8L3U+IHRpdGxlZCAqKjctR2l0KiouDQo8YnI+PC9icj4NCg0KPiBUaXA6IHZhcmlvdXMgYXBwbGljYXRpb25zIGRpc2xpa2UgdGhlIHV0aWxpemF0aW9uIG9mIHNwYWNlcyBpbiB5b3VyIGRpcmVjdG9yeSBwYXRoLiBJdCdzIGdvb2QgdG8gZ2V0IGluIHRoZSBoYWJpdCBvZiByZXBsYWNpbmcgdGhlbSB3aXRoIHVuZGVyc2NvcmVzIG9yIGRhc2hlcy4NCjxicj48L2JyPiANCg0KTm93IHdlIG5lZWQgdG8gdXNlICoqR2l0IEJhc2gqKiBvciB0aGUgdGVybWluYWwgd2luZG93IHRvIHByb3ZpZGUgc29tZSBhY3Rpb25zIHZpYSBjb21tYW5kIGxpbmUuIFRoZSBmaXJzdCBjb21tYW5kIHdpbGwgYmUgdG8gY2hhbmdlIHRoZSB3b3JraW5nIGRpcmVjdG9yeSBmb3IgeW91ciBnaXQgcmVwb3NpdG9yeS4NCg0KYGBge2Jhc2h9DQpjZCB6Oi9TdHVkZW50cy9ZT1VSIE5BTUUvNy1HaXQNCmBgYA0KDQpvciBpbiB0aGUgdGVybWluYWwgd2luZG93DQoNCmBgYHtiYXNofQ0KY2QgXFN0dWRlbnRzXFlPVVIgTkFNRVw3LUdpdA0KYGBgDQoNClRoaXMgd2lsbCBkaXJlY3QgKipHaXQqKiB0byBpZGVudGlmeSB0aGUgYXBwcm9wcmlhdGUgZm9sZGVyIHRvIGluaXRpYXRlIHRoZSByZXBvc2l0b3J5LiBJbml0aWFsaXppbmcgdGhlIGZvbGRlciBsZXRzICoqR2l0Kioga25vdyBpdCBuZWVkcyB0byBiZSB0cmFja2VkIGZvciBjaGFuZ2VzLiBUaGlzIGNhbiBiZSBkb25lIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoNCg0KYGBge2Jhc2h9DQpnaXQgaW5pdA0KYGBgDQoNClRoZSB0ZXJtaW5hbCB3aW5kb3cgc2hvdWxkIHJlc3BvbmQgd2l0aCAiSW5pdGlhbGl6ZWQgZW1wdHkgR2l0IHJlcG9zaXRvcnkgaW4gWjovU3R1ZGVudHMvWU9VUiBOQU1FLzctR2l0Ly5naXQvIiBhbmQgc2hvdyB0aGUgZGlyZWN0b3J5IGFzIC96L1N0dWRlbnRzL1lPVVIgTkFNRS83LUdpdCAobWFzdGVyKQ0KDQpJZiB5b3UgbmF2aWdhdGUgdG8geW91ciBzdHVkZW50IGZvbGRlciBvbiB0aGUgWjogRHJpdmUgeW91IHNob3VsZCBub3cgc2VlIGEgbmV3IGZvbGRlciAqLmdpdCogdGhhdCB3YXMgY3JlYXRlZC4gV2l0aGluIHRoYXQgZm9sZGVyIHRoZXJlIHNob3VsZCBiZSBhIG51bWJlciBvZiBvdGhlciBmb2xkZXIgYW5kIGZpbGVzLiBJZiB5b3Ugd2FudCB0byBzZWUgaW5mb3JtYXRpb24gcmVnYXJkaW5nIHRoaXMgZm9sZGVyIHlvdSBjYW4gdHlwZToNCg0KYGBge2Jhc2h9DQpnaXQgc3RhdHVzDQpgYGANCg0KR2l0IHdpbGwgdGhlbiByZXBvcnQgdGhlIGxldmVsIG9mIHRoZSBwcm9qZWN0IChicmFuY2ggbWFzdGVyKSwgd2hldGhlciB0aGVyZSBhcmUgY3VycmVudCBjb21taXRzIChObyBjb21taXRzIHlldCkgYW5kIHN0YXRlIHRoZXJlIGlzICJub3RoaW5nIHRvIGNvbW1pdCAoY3JlYXRlL2NvcHkgZmlsZXMgYW5kIHVzZSAiZ2l0IGFkZCIgdG8gdHJhY2spIiBpbmZvcm1hdGlvbiB3aXRoaW4gdGhlIHByb2plY3QgZm9sZGVyLiBOb3cgaXQgaXMgdGltZSB0byBiZWdpbiBhZGRpbmcgZmlsZXMgYW5kL29yIGZvbGRlcnMgdG8gYmUgdHJhY2tlZCBieSAqKkdpdCoqLiBUbyBkbyB0aGlzIHlvdSBjYW4gc2ltcGx5IGRyYWcgYW5kIGRyb3AgZmlsZXMgZnJvbSBhIHByZXZpb3VzIGV4ZXJjaXNlIG9yIGZyb20gYSBuZXcgcHJvamVjdC4gU28gbGV0cyBzdGFydCBieSBhZGRpbmcgdGhlIGluZm9ybWF0aW9uIGZyb20geW91ciAqMS1NYXJrZG93biogKGRhdGEsIHNjcmlwdHMsIGFuZCBodG1sKSB0byB0aGUgbmV3ICoqNy1HaXQqKiBmb2xkZXIgeW91IGNyZWF0ZWQgYWJvdmUuIFlvdSBjYW4gdXNlIHRoZSBgYGBsc2BgYCBjb21tYW5kIGluIGJhc2ggb3IgYGBgZGlyYGBgIGluIHRoZSB0ZXJtaW5hbCB3aW5kb3cgdG8gc2VlIHRob3NlIGZpbGVzIGluIHRoZSBuZXcgZm9sZGVyLg0KDQpPbmNlIHlvdSBoYXZlIGZpbGVzIGFkZGVkIHRvIHRoZSBmb2xkZXIgeW91IGNhbiBjaG9vc2UgdG8gdHJhY2sgdGhlIGNoYW5nZXMgb24gYW4gaW5kaXZpZHVhbCBmaWxlIHVzaW5nOg0KDQpgYGB7YmFzaH0NCmdpdCBhZGQgPGZpbGUgbmFtZT4NCmBgYA0KDQpBbHRlcm5hdGl2ZWx5IHlvdSBjYW4gbWFyayBldmVyeSBmaWxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoNCg0KYGBge2Jhc2h9DQpnaXQgYWRkIC4gDQpgYGANCg0KRm9yIHRoaXMgZXhhbXBsZSwgZ28gYWhlYWQgYW5kIHVzZSB0aGUgY29tbWFuZCB0byBhZGQgYWxsIG9mIHRoZSBhZGRlZCBmaWxlcyBhbmQgZm9sZGVycy4gT25jZSB5b3UgaGF2ZSBhZGRlZCB0aGVzZSBmaWxlcywgcnVuIHRoZSBgYGBnaXQgc3RhdHVzYGBgIGNvbW1hbmQgYWdhaW4uIFRoaXMgc2hvdWxkIHByb3ZpZGUgeW91IHdpdGggZGV0YWlscyByZWdhcmRpbmcgdGhlIG51bWJlciBvZiBmaWxlcyBtYXJrZWQgaW4gdGhlIHJlcG9zaXRvcnkuIFRoaXMgaXMgYWxzbyBjYWxsZWQgKnN0YWdpbmcgZmlsZXMqLiBZb3Ugd2lsbCBzZWUgdGhpcyB0ZXJtaW5vbG9neSB3aGVuIHdlIGJlZ2luIHRvIHVzZSAqKkdpdCoqIGFuZCAqKkdpdEh1YioqIHdpdGggUlN0dWRpby4NCg0KSWYgeW91IHdhbnQgdG8gcmVtb3ZlIGEgZmlsZSBvbmNlIGl0IGhhcyBiZWVuIHN0YWdnZWQgeW91IGNhbiB1c2UgdGhlIGZvbGxvd2luZyBjb21tYW5kOg0KDQpgYGB7YmFzaH0NCmdpdCBybSAtLWNhY2hlZCA8ZmlsZSBuYW1lPg0KYGBgDQoNCkluIG9yZGVyIHRvIGZpbmFsaXplIHRoaXMgcmVwb3NpdG9yeSwgeW91IG11c3QgKmNvbW1pdCogKHNvcnQgb2YgdGhlICoqR2l0KiogdGVybSBmb3Igc2F2ZSkgdGhlc2UgZmlsZXMuIFRvIGRvIHRoYXQsIHlvdSBtdXN0IGFsc28gYWRkIGEgY29tbWl0IG1lc3NhZ2UuIFRoaXMgbWVzc2FnZSBzaG91bGQgYmUgY29uY2lzZSBhbmQgZGV0YWlsIHRoZSBjaGFuZ2VzIG9yIGFkZGl0aW9ucyB0aGF0IGFyZSBiZWluZyBtYWRlLiBGb3IgZXhhbXBsZSwgeW91IGNvdWxkIHNheSAiYWRkaW5nIHJtZCIgb3IgInVwZGF0ZWQgciBzY3JpcHQiIG9yIHNvbWV0aGluZyBzaW1pbGFyIHRvIHRoYXQuIFVzZSB0aGUgZm9sbG93aW5nIGNvbW1hbmQgdG8gY29tbWl0IHRoZSBjaGFuZ2VzIGFuZCBhZGQgeW91ciBvd24gY29tbWl0IG1lc3NhZ2UuDQoNCmBgYHtiYXNofQ0KZ2l0IGNvbW1pdCAtbSAiUGxhY2UgdGhlIHJlcXVpcmVkIGNvbW1pdCBtZXNzYWdlIGhlcmUiDQpgYGANCg0KV2hlbiB3ZSBiZWdpbiB0byB1dGlsaXplICoqR2l0SHViKiogZm9yIHZlcnNpb24gY29udHJvbCB3ZSB3aWxsIHVzZSB0aGUgKnB1c2gqIGNvbW1hbmQgdG8gYWRkIHRob3NlIGNoYW5nZXMgdG8gYW55IGNvZGUgc2hhcmluZyBzaXRlLiBIb3dldmVyLCBmb3IgdGhpcyBleGFtcGxlIHdlIHdpbGwgbm90IG5lZWQgdGhlICpwdXNoKiBjb21tYW5kLg0KDQpgYGB7YmFzaH0NCmdpdCBwdXNoDQpgYGANCg0KVG8gdGVzdCB5b3VyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHByb2Nlc3MgYWJvdmUsIGNyZWF0ZSBhIG5ldyAqdGV4dCBmaWxlKiBpbiB0aGUgZGlyZWN0b3J5IGNhbGxlZCB0ZXN0LnR4dCBhbmQgdHJ5IHJlcGVhdGluZyB0aGUgc3RlcHMgYWJvdmUgdXNpbmcgdGhlIGBgYGdpdCBhZGQgdGVzdC50eHRgYGAgY29tbWFuZC4gVGhlbiBjb21taXQgdGhlIGZpbGUgdXNpbmcgYW4gYXBwb3JwcmlhdGUgY29tbWl0IG1lc3NhZ2UuIFdoZW4gZmluaXNoZWQgdXNlIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoNCg0KYGBge2Jhc2h9DQpnaXQgbG9nDQpgYGANCg0KV2hhdCBkb2VzIHRoaXMgdGVsbCB5b3U/DQoNCiMjIyBHaXQgSWdub3JlDQoNCklmIHlvdSBkb24ndCB3YW50IHRvIGNvbW1pdCBhbGwgb2YgdGhlIGZpbGVzIGluIGEgZ2l2ZW4gcHJvamVjdCB5b3UgY2FuIGNyZWF0ZSBhICoqLmdpdGlnbm9yZSoqIGZpbGUuIFRoaXMgaXMgYSBzaW1wbGUgdGV4dCBmaWxlIHRoYXQgY3JlYXRlcyBydWxlcyBmb3IgYWxsIHVzZXJzIG9mIHRoZSBwcm9qZWN0IHRvIGlnbm9yZSBjb21taXR0aW5nIHBhcnRpY3VsYXIgZmlsZXMgb3IgZm9sZGVycy4gVGhpcyBmaWxlIHNob3VsZCBiZSA8dT5zdGFnZWQgYW5kIGNvbW1pdHRlZDwvdT4gdG8gdGhlIHJlcG9zaXRvcnkgc28gaXQgaXMgZ2xvYmFsbHkgYXZhaWxhYmxlIGZvciBhbGwgdXNlcnMuIA0KDQpUbyBjcmVhdGUgdGhlICouZ2l0aWdub3JlKiBmaWxlLCB0eXBlIHRoZSBmb2xsb3dpbmcgY29tbWFuZDoNCg0KYGBge2Jhc2h9DQp0b3VjaCAuZ2l0aWdub3JlDQpgYGANCg0Kb3IgaW4gdGhlIHRlcm1pbmFsIHdpbmRvdw0KDQpgYGB7YmFzaH0NCnR5cGUgbnVsID4gLmdpdGlnbm9yZQ0KYGBgDQoNCk9uY2UgeW91IGhhdmUgY3JlYXRlZCB0aGUgZmlsZSwgbmF2aWdhdGUgdG8geW91ciBzdHVkZW50IGRyaXZlIGFuZCByaWdodCBjbGljayBvbiB0aGUgZmlsZSB0byBvcGVuIHdpdGggYSB0ZXh0IGVkaXRvciBzdWNoIGFzIENvZGUgV3JpdGVyLCBOb3RlUGFkLCBbVGV4dFBhZF0oaHR0cHM6Ly93d3cudGV4dHBhZC5jb20pLCBbVmlzdWFsIFN0dWRpbyBDb2RlXShodHRwczovL2NvZGUudmlzdWFsc3R1ZGlvLmNvbS8pLCBXb3JkUGFkLCBldGMuIFRoZSBzYW1lIHRleHQgY29tbWVudGluZyBzeW50YXggdGhhdCBvcGVyYXRlcyBpbiBwcm9ncmFtcyBsaWtlICoqUioqIGFsc28gd29yayBoZXJlLiBTbyBpZiB5b3UgaW5jbHVkZSBhICoqIyoqIHRoaXMgd2lsbCBiZSB0cmVhdGVkIGFzIGEgY29tbWVudCwgYmxhbmsgbGluZXMgbWF0Y2ggbm8gaW5mb3JtYXRpb24gc28gYXJlIG5vdCBydW4gYW5kIGNhbiBiZSB1c2VkIGFzIHNlcGFyYXRvcnMgZm9yIGxlZ2liaWxpdHksIGV0Yy4gDQoNCkluIHRoZSAqLmdpdGlnbm9yZSogZmlsZSwgSSBnZW5lcmFsbHkgbGlrZSB0byBiZWdpbiB3aXRoIGEgY29tbWVudCByZWdhcmRpbmcgd2hhdCBuZWVkcyB0byBiZSBpZ25vcmVkLiBUaGUgZm9sbG93aW5nIGlzIGEgc2ltcGxlIGV4YW1wbGU6DQoNCmBgYA0KI0lnbm9yZSB0aGVzZSBmb2xkZXJzDQppbWFnZXMvDQpleGFtcGxlcy8NCg0KI0lnbm9yZSB0aGVzZSBmaWxlIHR5cGVzDQoqLmN2cw0KKi50eHQNCiouZG9jeA0KKi54bHN4DQoNCiNJZ25vcmUgdGhlc2UgZmlsZXMNCnRlc3RfbmIuUm1kDQouUmhpc3RvcnkNCmBgYA0KU2luY2UgdGhlICouZ2l0aWdub3JlKiBmaWxlIGlzIHN0b3JlZCBpbiB5b3VyIHJlcG9zaXRvcnksIHlvdSBkb24ndCBuZWVkIHRvIHByb3ZpZGUgdGhlIGVudGlyZSBwYXRoIHRvIHNwZWNpZmljIGZpbGVzIG9yIGZvbGRlcnMuICoqR2l0KiogYW5kICoqR2l0SHViKiogd2lsbCBzZWFyY2ggdGhlIGVudGlyZSByZXBvc2l0b3J5IGFuZCBsaXN0IG9mIGNvbW1pdHMgdG8gaWdub3JlIHRoZSBmaWxlcyBpZGVudGlmaWVkIGluIHRoZSAqLmdpdGlnbm9yZSogZG9jdW1lbnQuIEJlIHN1cmUgdG8gYWRkIGFuZCBjb21taXQgdGhlIGZpbGUgb25jZSBpdCBoYXMgYmVlbiB1cGRhdGVkLg0KDQojIyBGaW5hbCBUaG91Z2h0cw0KDQpBdCB0aGlzIHBvaW50IHlvdSBoYXZlIGluaXRhbGl6ZWQgYSBmb2xkZXIsIHN0YWdnZWQgZmlsZXMsIGFuZCBjb21taXR0ZWQgdGhlbS4gR2VuZXJhbGx5IHNwZWFraW5nLCB3ZSB3aWxsIHJlcGVhdCBhbGwgb2YgdGhlc2Ugc3RlcHMgd2l0aGluICpSc3R1ZGlvKiBpbiB0aGUgbmV4dCBleGVyY2lzZS4gSG93ZXZlciwgKipHaXQqKiBjYW4gYmUgdXNlZCBsb2NhbGx5LCB3aXRob3V0IGEgY2xvdWQtYmFzZWQgcmVwb3NpdG9yeSwgYW5kIGlzIGEgZ3JlYXQgd2F5IHRvIG1hbmFnZSBsb25nLXRlcm0gcHJvamVjdHMuIEV2ZW4gaWYgeW91IGFyZW4ndCB1c2luZyBbKipHaXRIdWIqKl0oaHR0cHM6Ly9naXRodWIuY29tLyksIHlvdSBzaG91bGQgcHJvYmFibHkgZ28gYWhlYWQgYW5kIFtjcmVhdGUgYW4gYWNjb3VudF0oaHR0cHM6Ly9naXRodWIuY29tL2pvaW4pLCB0aGV5IHByb3ZpZGUgYSBzdW1tYXJ5IFtjaGVhdHNoZWV0XShodHRwczovL2dpdGh1Yi5naXRodWIuY29tL3RyYWluaW5nLWtpdC9kb3dubG9hZHMvZ2l0aHViLWdpdC1jaGVhdC1zaGVldC5wZGYpIGZvciBjb21tb25seSB1c2VkIEdpdCBjb21tYW5kcy4gVGhpcyBjYW4gYmUgaGVscGZ1bCBpZiB5b3UgZm9yZ2V0IHNvbWUgb2YgdGhlIGJhc2ljIGluc3RydWN0aW9ucyBmb3IgY3JlYXRpbmcgcmVwb3NpdG9yaWVzLCBzdGFnaW5nIGZpbGVzLCBjb21taXQgYW5kIGNvbW1lbnRpbmcsIG9yIGp1c3QgdG8gW2dpdCBieV0oaHR0cHM6Ly95b3V0dS5iZS9VVnRwWHZ6elhpQT90PTIyKS4NCg0KIyBZb3VyIFR1cm4hDQpVc2luZyB0aGUgc2tpbGxzIHlvdSBhY3F1aXJlZCBhYm92ZSwgY3JlYXRlIGEgZ2l0IHJlcG9zaXRvcnkgZm9yICoqRXhlcmNpc2UgMioqIHRpdGxlZCAqMi1HTE0qLiBJbiB0aGlzIHJlcG9zaXRvcnkgPHU+aW5jbHVkZTwvdT4gdGhlICptYXJrZG93biBkb2N1bWVudCosICpodG1sIGZpbGUqLCBhbmQgdGhlICoqUioqICpwcm9qZWN0IGZpbGVzKi4gQWRkaXRpb25hbGx5LCBjcmVhdGUgYSAqLmdpdGlnbm9yZSogZmlsZSB0byA8dT5leGNsdWRlPC91PiBhbnkgKmltYWdlIGZpbGVzKiB5b3UgY3JlYXRlZCwgdGhlICpleGNlbCBkYXRhc2V0KiwgYW5kIGFueSAqYW5jaWxsYXJ5IGZvbGRlcnMqLg0KDQojIyBBZGRpdGlvbmFsIEhlbHANCg0KQWZ0ZXIgY3JlYXRpbmcgdGhpcyBleGVyY2lzZSBJIHN0dW1ibGVkIG9udG8gdGhpcyBZb3VUdWJlIHZpZGVvLCBbTGVhcm4gR2l0IEluIDE1IE1pbnV0ZXNdKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9VVNqWmNmajh5eEUmdD02MDJzKSwgZnJvbSBbQ29sdCBTdGVlbGVdKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNycUFHVVBQTU9kbzBqZlE2Z3Jpa1p3L2ZlYXR1cmVkKS4gVGhpcyB2aWRlbyBwcm92aWRlcyBhIGZhbnRhc3RpYyB2aXN1c2FsLCBzdGVwLWJ5LXN0ZXAgbG9vayBhdCBzZXZlcmFsICoqR2l0KiogY29tbWFuZHMuIElmIHlvdSBydW4gaW50byBpc3N1ZXMgbW92aW5nIGZvcndhcmQgdGhpcyB2aWRlbyBjYW4gbGlrZWx5IGFuc3dlciB5b3VyIHF1ZXN0aW9uLCBhbmQgcmVtZW1iZXIsIFtHb29nbGVdKGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20pIGlzIHlvdXIgZnJpZW5kLg0K