SE2030
Git Setup

Copy the SSH URL:
 * If you already pulled it with https, get the new url and reset the url with a command something like ```git remote set-url origin git@github.com:username/repositoryname.git``` (Following https://confluence.atlassian.com/bitbucket/change-the-remote-url-to-your-repository-794212774.html) ## IntelliJ Setup To create a new IntelliJ project and check it into a blank Git project: 1. Clone the empty repository with ```git clone ______.git``` where the URL comes from the github page's "Clone this repository" link. I recommend getting the SSH link rather than the HTTP (once you set up SSH keys as above) 1. Create a .gitignore file containing ``` .idea/workspace.xml out/ ``` 1. Check this in like any other file. 1. Create an empty IntelliJ JavaFX project however you usually do it. Confirm the main window opens. 1. Copy the contents of your IntelliJ project into the contents of your empty git repo. Your .idea folder should show up side-by side with the .git folder if you have done this correctly. Ask me for help if it doesn't. (From the command prompt, use ```ls -a``` to show folders starting with a dot (.) 1. Run ```git status```. It should show your intelliJ files in red. 1. Open this folder as an IntelliJ project. While opening it, it should recognize your top level git folder as an IntelliJ Project. If it does not, do not open the project. Ask for my help at that point. (If you open the project, it will create another IntelliJ project, which is undesirable here!) 1. Confirm that the window still pops up when you run it from your git project. 1. Run ```git status``` again. (I'm kind of compulsive about this -- it's hard to undo stuff if you make a mistake in Git) 1. Run ```git add .``` to add ALL the files that showed in red in the previous command. 1. Run ```git commit -m "Fresh IntelliJ JavaFX Project"``` to commit to your local repository 1. Run ```git push``` to push the files up to the server Now, a second teammate should test the repository: 1. Run ```git clone ____.git``` as above (Or ```git pull``` from within your git directory if you've already cloned it). This pulls down the full project from remote to your local repository, local index, and local working directory. 1. Confirm the .idea folder and src/...fxml file are present. 1. Open this folder as an IntelliJ project. While opening it, it should recognize your top level git folder as an IntelliJ Project. If it does not, do not open the project. Ask for my help at that point. (If you open the project, it will create another IntelliJ project, which is undesirable here!) 1. Confirm that the window still pops up when you run it from your git project. Congratulations! You now have a complete starting repository! I find this [tutorial on Git](https://githowto.com/checking_status) to walk through the sorts of things I would like to teach about Git. This link skips past the setup page, since we do that together in class. ## Fancy git log This command shows a graphical history similar to what you would see on GitHub. ``` git log --graph --decorate --pretty=oneline --abbrev-commit ``` ## Cleaning up messes in Git I strongly recommend avoiding messes in the first place: * ```git status``` before ```git add .``` and ```git commit -m "..."``` * Frequent commits to the shared branch when possible to reduce messy merges * Separate branches when development will take more two commits or when intermediate results will break the current dev branch in some way. (Non-compiling commits MUST be off of the master and dev branches and SHOULD contain a clear message that they don't compile.) In many cases, the quickest way to clean up a mess is to use the ["xkcd approach"](https://xkcd.com/1597/). This can work even if you want to keep your changes: * Re-clone the project in a new folder besides the old project (```cd``` out of your git folder. ```ls``` to confirm you can see your folder, but aren't inside it. Then clone as you did at first, but specifying a destination folder: ```git clone _______.git projectN```. I recommend updating N every time you have to do this, and deleting the old copies once you are sure there is nothing you need in them.) * Copy your changes to the re-cloned project. (E.g., if you were in project4, copy your changes to project5) * Pull, confirm it compiles, then add, commit, and push your changes to the server as usual. It's a fail-safe approach! (Then, once you are sure it worked, remember to delete your old directory so you don't get confused about which one to use!) There is one case where this does not work well. That is if you have attempted a pull, and the merge that comes as part of the pull fails. If there have been many new changes merged in from the remote branch, you may find it hard to extract the code you want to save. In that case, you may want to roll back to your last commit. ***Make sure there are no untracked files in your old worspace that you care about*** and [do a reset](https://stackoverflow.com/questions/1223354/undo-git-pull-how-to-bring-repos-to-old-state) in your old project using the command ```git reset --merge``` or ```git reset --hard```. This will undo the failed merge and go back to the version of your code before you did the pull. See the section on wiping your working directory and returning to the latest commit for more information. I have found there are some subtleties here. I have a flowchart that I wish to typset and place here So I recommend the xkcd approach if you ever have a mess. But, if you still want to practice your [git kung-fu](https://devrant.com/rants/855450/a-poem-for-git-in-git), here we go: ### The ```git mergetool``` ### When you do a ```git pull``` or ```git merge ...```, git will attempt to automatically merge the changes on your local branch with either the merges from the remote server or whatever branch you specify (respectively). If their are overlapping changes between the two branches, the automatic merge will fail. Git will not create the new commit. It will instead wait for you to manually edit the files to resolve the conflicts, add the files, and commit them as usual. However, git **does** store several versions of the file for which the merge failed: The latest versions from the two branches you are merging (e.g. your local branch and the branch on the server), the original version that both branches are derived from, and the automatically merged version that is in your working directory. (The other three files are in the index somewhere.) One of the most convenient ways to use these files is to use ```git mergetool``` to view them all at the same time. When you run ```git mergetool```, it opens up a window with all four files: The latest commit on the local bracnch on the left, the common anscestor in the middle, and the latest commit on the other branch on the right. Underneath all of these, it shows the merged version that is in the workspace. This can help you to see where the changes come from that show up in the merged version. **However,** you need to use an editor that is designed to perform a merge like this. The default editor is ```vimdiff```, based on the ```vim``` editor. You will need to know a few keybindings to use this editor: Pressing Control-w and then an arrow key will move you between the windows in this editor. The arrow keys (or, if you prefer, j, k, l, and h) will move the cursor around the screen. dd deletes a whole line. Pressing i takes you into *insert* mode where you can type text or delete existing text. Pressing the escape key takes you out of editing mode. When you are done editing the file in ```vimdiff``` within the ```git mergetool``` command, you can press :xa and then enter to save and close all files, or :qa! and then enter to close all files without saving. Once you do either of these, the ```git mergetool``` is complete. You cannot start it again without undoing the merge. (If you do want to undo the merge, simply use ```git reset --merge```. But you might also have to do ```git status``` and the use ```rm somefile.orig``` to delete any files that you edited) **As an alternative to the command-line ```git mergetool```, you can use IntelliJ's built-in merge conflict resolution tool. To do this, identify the file that has merge conflicts in IntelliJ. It should show up in red. Right-click just about anywhere and select "Git->Resolve Conflicts...```. This opens the _Files Merged with Conflicts_ window. Double-click on the file whose conflicts you wish to resolve. You will see a window that looks like this:

at the top of the window. When you are done, press "Apply" to save your changes, or "Abort" to close the window without saving them.
Github also released 'Github desktop' which has a nice merge conflict resolution tool builtin. However, we prefer that for everything except merges, you learn to do the git management from the command prompt.
### Cleaning up a git mess: General notes ###
For general guides to undoing stuff in Git, see [1] and [5].
Throughout this section, I use the term "working directory" where most poeple would say "working tree" [6]. Both terms mean the same thing in this context: All the folders and their subfolders in my git project, excluding the .git folder itself which is ignored by git.
I distinguish "working directory" (by which I mean the whole working tree) from "current folder and all its subfolders" (which does not include folders above the current folder in the working directory)
Note that IntelliJ also tracks local history, so you can sometimes recover lost files through that even when you have completely removed them from .git (I don't recommend relying on this behavior!)
### Wipe directory and return to latest commit.
If you want to discard EVERYTHING that you have changed since the last commit, use these commands. You can also use these commands if you want to undo a messy ```git merge``` or ```git pull```, since ```merge``` and ```pull``` do not create a new commit if the automatic merge fails.
These commands wipe out ALL changes since the last commit. You must run them commands from within the topmost folder of your project because the ```git clean``` command only works from the current directory and its sub-directories. [4]
```
git status # Check to see what we are about to discard.
git reset --hard
git clean -dfxn # Check what the next command will delete before running it.
git clean -dfx
```
Original source: [2b]
Notes on the flags used with ```git clean```:
```
# Add -n to check if you want to remove those files, e.g. git clean -ndfx
# -f: force: You MUST use this option to get ANY files deleted by this command
# (It's required for safety)
# -d: delete directories;
# -x: delete even .gitignored files (which are, of course, not backed up by git)
```
If you would like to do the equivalent of the xkcd command (without saving anything in your local repository!) see, the section on an exhaustive wipe below.
### Individual files ###
In this section, we undo a git procedure one file at a time.
```
git reset