Guide to FS Open and git
Contents
Getting the source: Tortoise Git
(based on a previous revision of Getting_the_FreeSpace2:_SCP_Source_Code)
- Download and install Git For Windows (this is a dependency for TortoiseGit)
- Download and install TortoiseGit (you probably need to reboot after installing)
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Simple Development: Tortoise Git
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
- Note: The previous three steps can be done as a single step if you have recently pushed a branch by selecting the "Compare and Pull Request" button
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
- That's it! Now wait for the pull request to be reviewed and committed to primary FSO master branch
Syncing: Tortoise Git
Pushing
This section will go over synchronizing your local git repo with a remote
Once you've committed to your local git repo and verified its integrity (a simple build-check will suffice), you should update the remote repo through the "Push" process.
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
The Push dialog is displayed. From here, you can push one or more branches from one repo to another, local and remote alike. The "Ref" control group will be the repo that will be pushed onto the repo specified in the "Destination" control group. If you are managing multiple remotes, you may also push one remote to another. For now, we'll focus on just pushing our local repo onto the remote.
If a conflict between the remote repo and your local repo arises, git will halt the push. Otherwise it should complete as shown below. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Pulling
This section will go over pulling commits from an "upstream" remote (assuming that you're developing in a github forked repo and you want to get new commits from the "official" repo)
If you don't already have it, add the official repo as a remote called "upstream"
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
The defaults in the next screen are fine, click OK to "fetch" all the "upstream" commits |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Now we "pull" the commits from the upstream master into our own master
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
We're back to the previous window. Note how the remote repo and remote branch dropdowns are set to upstream/master
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Resolving Conflicts
This is a simple example of how to resolve a conflict that occurs when you try to push changes to a public repo. This example specifically used:
- A github "personal" repo cloned from another "master" repo
- A branch with conflicting changes; one computer committed changes to a file, while the 2nd computer (running TGit) committed changes to the same lines in that file.
- And yes, the changes are silly
Here's the commit from the other computer. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Here's the commit in your local repo that you're about to push to the same branch. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
As expected that didn't work... |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
As suggested, try a pull with the default options. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
As expected we have merge conflicts. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
At this "yes / no" prompt either options can be picked, it'll be a bit quicker to pick "yes" if you want to resolve the conflict now. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
If you didn't pick yes in the previous step, you can get this window by select "Diff" from the TGit menu
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
"Resolve the conflict" (often simpler said than done). Some tips are available here. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Since this is a trivial example, I've used an equally trivial resolution of taking one line from remote repo and one from the local repo.
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
A prompt should appear asking if you want to mark the conflict as resolved.
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Note that the Diff window hasn't updated, it still says the file has a conflict :/ If you double click on the file however, nothing will happen.
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Commit your changes
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
The commit was successful. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Now back to what was originally wanted - push the changes to the remote repo
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Success! |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Collaboration with remotes: Tortoise Git
Here we'll go through:
- adding a remote branch from someone else's repository
- committing to that branch and pushing it back to your own repository
You may do this when you're collaborating on a feature prior to it being committed to the master
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Patches: TortoiseGit
(from http://www.hard-light.net/forums/index.php?topic=83453.msg1736781#msg1736781, written by m!m)
Creating Patches
Just choose the "Create Patch Serial" from the context menu. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
In the window choose from which point onwards the patch should be created, master is probably a good idea. Once you hit OK TGit will create a number of patch files in your repository which you can then transfer to the other repository. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Applying patches
To apply a patch serial choose "Apply Patch Serial". You will need to select the patch files from the previous step and possibly rearrange them (in most cases the default ordering should be sufficient though). |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Hit Apply and TGit will start creating commits with the changes in the patch files. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
If there are conflicts you will need to resolve or skip them. |
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
When that is finished you will have all the changes from the patches in your repository.
Applying old patches plus conflict resolution: TortoiseGit
Here's one way to apply old patches using git. When I say "old patch", I mean a patch that you almost certainly know is going to have conflicts. This is based off a technique I've used with the git command line. It may be that TortoiseGit provides alternate ways of achieving this, however the advantage of this technique is that it's very similar to the conflict resolution that you may need to do when syncing your repo (plus I have a good example in one of Axem's patches that's been floating around for... nearly 2.5 years!) And I really hate dealing with .rej files, I find the graphical tools used in this method make conflict resolution much easier (of course YMMV depending on your experience/preference!)
Steps
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
Now we're onto something new - you are going to "rebase" the current master onto your branch. The sequence of steps is basically, remove the patch you applied, then in order apply all the commits from master to your branch, *and then* reapply the patch "on top" of all those changes. This is different to a "merge" which is more like applying all the commits from master "on top" of your current patch Warning: DO NOT EVER perform a rebase on a branch that you have pushed to a public repository. A rebase changes the previously published commit history which will cause pain for anyone else who has started using your published branch. Perform a "merge" instead. Or maybe create a new branch based off your existing branch, then rebase *the new* local branch and push to a *new* public branch.
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
|
|
Git Command Line Equivalent: {{{cmdlinetxt}}} |
- Once all the files with conflicts are resolved, click "Commit" to complete the process
- TortoiseGit -> Show Log is very useful to double check that you got the commit right before pushing it to a public repo
- If you didn't get it right, edit the files in your normal IDE to fix the mistakes, make another commit and "squash" the two commits together before pushing to a public repository
- As a last resort if the rebase is beyond saving, simply delete the branch and start again
TortoiseGitMerge Tips
Merge Conflict Tips:
- The best way to resolve merge conflicts is to avoid them altogether in the first place. This is because it's more likely to induce bugs or unintended behavior whenever manual conflict resolutions come into play.
- Git offers a few conflict resolution strategies. See the Git documentation on "git merge -strategy" to see if one of them can solve most of the conflicts for you.
- Never, Ever, try to resolve the conflicts by writing your own .diff or patch. Use the merge tools available to you. Besides simple "Theirs, Mine" resolutions, most of them allow editing, too.
- If possible, find a merge tool that show you four windows: (unfortunately TGitMerge doesn't do this, only merge tool like this that I've found so far is kdiff3)
- Your changes
- Their changes
- Output / merged results
- Common ancestor (this is what most tools seem to omit - showing the original code can really clarify what's going on without needing to open another window & find the ancestor yourself)
Local Merge Conflicts: Merging branches
- If you find that a branch has conflicts when doing a merge, retrieve the commit log for the branch your merging into and save the commit as a unified diff. Use this as a reference during conflict resolutions to ensure you get only the changes that you have made.
- If you find that a branch has conflicts with files that have nothing to do with the changes you made in the commit, you can quickly choose "Solve Conflict Using Theirs" or "Solve Conflict Using Mine" from the commit dialog by right clicking on the file. This will help reduce the number of files you'll have to spot check to just the ones you made changes to.
Lastly, here's a list of some of the tools offered by TortoiseGitMerge which can help with conflict resolution (the list has some overlap with stuff I've already mentioned)
- Right click the line numbers in the "theirs" or "mine" windows to select "text blocks" which will be applied to the "merged" window
- For simple conflicts you can choose "theirs then mine" or vice versa from the right click menu
- By clicking on the line numbers on the left hand side you can select individual lines to apply
- Similarly you can select multiple lines by click/dragging on the line numbers
- When "theirs/mine" lines are selected another right-click option becomes available, "copy". These lines can then be pasted to "merged"
- You can also make edits in the "merged" window just like any other text editor
- Use the "Next/Previous Commit" buttons to rapidly find the conflicts
- Click the "Mark as Resolved" button when you're done. This not only saves your changes/selections, but also clears the conflict flags from the file. If the commit dialog still shows the resolved file as in-conflict, you can right click on the file name and select "Resolved" to mark it as resolved.
General Repo Housekeeping
Doing a full fork of the scp-fs2open codebase will likely leave you with a number of branches that won't be of much interest to you. Thankfully, you can prune off the unwanted/unneeded branches from your fork leaving only the branches you will be working on. Should you decide that you want to see what's going on in any of the other branches (such as antipodes), you can still issue a pull from "upstream".
- Check out all the branches that you want to work on from origin onto your local machine
- In the git console, issue a "git push origin --prune" to start the process. Git may give you a warning message about the push.default setting, you may safely ignore this.
- Check on the status of your pruning using either github's web page or by issuing "git branch -r" to the git console