This repository demonstrates advanced Git operations as part of Assignment 2, following a Git Flow–like branching model.
The purpose is to practice merge, rebase, squash, and cherry-pick commands while managing conflicts and maintaining a clean project history.
The documentation branch is used exclusively for recording the workflow, describing branch purposes, and summarizing the strategy used in this assignment as required by the rubric.
All feature branches and the documentation branch originate from the main development branch (dev).
| Branch | Source Branch | Purpose | Description of Contents |
|---|---|---|---|
| main | – | Production / Stable | Contains the initial, working version of the Number Guessing Game. Will only receive changes from dev after testing and integration are complete. |
| dev | main |
Integration / Staging | Central branch where all features are merged, rebased, and tested before being pushed to main. |
| documentation | dev |
Documentation | Records the structure, workflow, and conflict resolutions. Includes this README file. |
| feature1 | dev |
Merge Practice | Adds a quit-game option and replay loop. This branch will be integrated into dev using a standard merge (Steps 2 & 3). |
| feature2 | dev |
Rebase Practice | Implements a maximum attempts feature and an encouraging message. It will be integrated into dev using rebase (Steps 4 & 6). |
| feature3 | dev |
Squash Practice | Adds a hint system that tells the player if their guess is close. Multiple commits will be squashed into one before merging into dev (Step 5). |
| hotfix | main |
Cherry-Pick Practice | Fixes the random number generation to correctly include the upper bound. This change will be cherry-picked to main and then merged back into dev (Step 7). |
- Start from
devto create the documentation branch. - Merge
feature1intodev(merge strategy). - Rebase
feature2ontodev, resolving conflicts as needed. - Squash multiple commits from
feature3into one and merge it intodev. - Cherry-pick the
hotfixcommit tomainand propagate it back todev. - Confirm that all tests pass on
devand finalize documentation.
Strategy:
A standard Git merge was used to integrate the work from feature1 into the integration branch, dev. This process included first updating the feature branch by merging the latest changes from dev (git merge dev while on feature1), and then merging the updated branch back into dev.
Conflict Resolution:
A conflict occurred in Main.java between a version comment introduced in feature1 and a new print statement added in dev.
Resolution: The conflict markers were manually removed, and both lines of code were kept to preserve all intended functionality. The final merged version reflects the combined updates from both branches.
Cleanup:
After verifying the merge was successful, the feature1 branch was deleted locally using git branch -d feature1 to maintain a clean and organized branch structure.
Verification: All tests passed successfully after each merge stage.
- When merging
devintofeature1, the build completed without errors after fixing the conflict inMain.java, and all feature tests passed. - The subsequent merge of
feature1back intodevwas completed as a fast-forward merge, confirming that no additional conflicts were introduced. Both merges were validated through successful test execution on thedevbranch, ensuring that the integration remained stable.
Strategy:
The feature2 branch was updated using a git rebase dev operation instead of a standard merge. This approach ensured a clean, linear commit history, stacking feature2’s commits directly on top of the latest dev branch. It also allowed resolving conflicts in an ordered, step-by-step manner while preserving both branches’ logic.
Conflict Resolution:
The rebase process encountered two sequential conflict stops caused by overlapping logic between the updated dev branch and feature2.
- Resolution Details:
- Stop 1 (Commit 45aa640):
Conflict inGameEngine.javain makeGuess(int guess) method between theuserQuitfunctionality fromdevand the newgameOver/MAX_ATTEMPTSlogic introduced infeature2.
The resolution combined both behaviors by keeping both fields and ensuring thatuserQuithandled exit conditions whilegameOvercontrolled the attempt limit. A missing closing brace (}) was also added in hasUserQuit() method. - Stop 2 (Commit e367776):
Conflicts occurred across three files and required simultaneous integration:GameEngine.java– Merged themakeGuessmethod logic forgameOverwith theuserQuithandling. Fixed a missing closing brace.GameUI.java– Integrated both loop conditions:while (!engine.isGameWon() && !engine.isGameOver())and!engine.hasUserQuit(). Added a missing closing brace.GameEngineTest.java– Merged test cases fortestQuitWithNegativeNumber(fromdev) with new tests such astestMaxAttemptsReachedandtestRemainingAttemptsDisplayed. Added a missing closing brace intestQuitDoesNotIncrementAttempts.
- After each conflict set was fixed, the changes were staged (
git add <filename>) and the process continued usinggit rebase --continueuntil all commits were successfully applied.
- Stop 1 (Commit 45aa640):
Verification:
Both intermediate and final builds compiled without errors after each conflict resolution.
All existing and new unit tests passed successfully, confirming that:
- The
feature2logic for maximum attempts and game-over state was correctly integrated. - The
feature1quit-game functionality remained intact. - The final rebase history was linear and clean on
dev, with no merge commits introduced.
Strategy:
The feature3 branch was refined using an interactive rebase (git rebase -i) to consolidate multiple small incremental commits into a single, meaningful commit. This approach ensured a cleaner, more readable project history by grouping related changes together.
Squash Process:
- Interactive Rebase: Four commits (
started hint,got it done,had to fix,done) were combined into one by keeping the first commit aspickand marking the following three assquash. - Consolidated Commit Message: The combined commit message was rewritten as "Add hint system to show proximity after 3 attempts", clearly summarizing the feature.
- Post-Squash Rebase: After squashing, a
git rebase devwas executed to alignfeature3on top of the latestdevhistory before integration.
Conflict Resolution during Rebase:
A single rebase conflict occurred across two files — GameEngine.java and GameEngineTest.java.
- Resolution:
- In
GameEngine.java, thehintsEnabledlogic introduced infeature3conflicted with the features fromdev.
The resolution involved merging all behaviors together within themakeGuess()method to ensure correct handling of hint generation. - In
GameEngineTest.java, the hint-related test cases (testHintVeryClose,testHintGettingWarmer, etc.) conflicted with the quit-game tests. The conflict was resolved by integrating both sets of tests and adding the missing closing brace (}) intestQuitDoesNotIncrementAttempts.
- In
After resolving each conflict, changes were staged with git add <filename> and the rebase process continued using git rebase --continue until all commits were successfully applied.
Integration:
Once rebasing was complete, the squashed feature3 branch was merged into dev using a Fast-Forward Merge, preserving a clean and linear history without introducing additional merge commits.
Verification:
The project compiled successfully, and all unit tests passed — including the newly added hint feature tests and the existing tests — confirming a stable and complete integration of all functionalities.
Cleanup:
After verifying a successful integration, the feature3 branch was keep locally for reference.
Strategy:
The final integration of feature2 ensured that all recent changes from dev—including feature1’s quit logic and feature3’s squashed hint feature—were properly synchronized before completing its final merge. This step guaranteed that all feature sets coexisted without conflicts in the unified development branch.
Synchronization and Conflict Resolution:
- The update (
git merge devintofeature2) produced merge conflicts in two key files:GameEngine.javaGameEngineTest.java
- Resolution:
- In
GameEngine.java, thefeature2logic (gameOverandMAX_ATTEMPTS) conflicted with thefeature3logic (hintsEnabledand hint generation). The solution required integrating all functionalities into a single, consistent implementation ofmakeGuess(int guess), ensuring proper handling of quitting, hint display, and attempt tracking. - In
GameEngineTest.java, overlapping tests for max attempts and hint-related behaviors required manual merging. The conflict was resolved by preserving both sets of tests and correcting one missing closing brace (}) in testResetClearsGameOver() method. - All conflict markers were removed, the code was verified to compile successfully, and changes were committed to finalize the merge on
feature2.
- In
Integration:
After conflict resolution, the updated feature2 branch was merged into dev using a Fast-Forward Merge, resulting in a clean, linear history without an additional merge commit.
Verification:
The project compiled successfully, and all unit tests passed—including those for quit logic, maximum attempts, and hint behavior—confirming that the three distinct feature sets were no
Cleanup:
After verifying a successful integration, the feature2 branch was keep locally for reference.
Objective:
To simulate an urgent production fix (hotfix) and practice propagating a pre-existing fix to the main and dev branches, ensuring both remain synchronized.
Hotfix Identification and Cherry-Pick (on main):
- The
hotfixbranch contained the commit “Fix randomInt to properly include max value in range” (ab7cd7b), which corrected the range logic inUtils.javaand added new test coverage inUtilsTest.java. - A successful
git cherry-pick hotfixwas executed on themainbranch, integrating the fix and the test file into the production branch. - Observation: A subsequent attempt to reapply the same commit using its hash (
git cherry-pick ab7cd7b) triggered an “empty commit” warning — confirming the hotfix had already been applied successfully in the first attempt.
Propagation to dev (Merge):
- The applied fix was then propagated to the development branch by performing
git merge mainondev. - This merge completed cleanly with no conflicts, confirming successful synchronization between the production and development branches.
Verification:
- The merge output showed the expected updates in
Utils.javaand the addition ofUtilsTest.java. - All unit tests passed, verifying that the hotfix integrated properly alongside existing feature branches (
feature1,feature2, andfeature3).
Cleanup:
- Since the
hotfixbranch was already merged and all changes were synchronized, no additional cleanup was required.
Overview:
This Git workflow successfully demonstrated a complete multi-branch development process involving merges, rebases, squashes, and cherry-picks.
Each strategy was applied in a realistic scenario to simulate collaborative software development and conflict resolution while maintaining a clean and traceable history.
| Strategy | Description | Effect on History | Typical Use Case |
|---|---|---|---|
| Merge | Combines changes from one branch into another by creating a merge commit. | Creates a non-linear history that preserves the original context of both branches. | When collaboration is frequent and preserving the full branch history is important (e.g., merging feature branches into dev). |
| Rebase | Moves or reapplies commits from one branch onto another base branch. | Rewrites commit history to create a clean, linear timeline. | When you want to integrate the latest changes before merging, or when maintaining a cleaner project history. |
| Squash | Consolidates multiple commits into one single commit before merging. | Produces a minimal, cleaner history representing a complete feature as one commit. | When a feature branch has many small “work-in-progress” commits that should appear as one logical change. |
| Cherry-Pick | Copies a specific commit from one branch and applies it to another. | Adds a duplicate commit (new hash) containing the same changes. | When you need to propagate an urgent fix (e.g., hotfix) to multiple branches without merging everything. |
- Feature1 (Merge):
Merging preserved the original commit history, showing both the feature commits and the merge commit itself. This reflects a typical integration pattern where history transparency is prioritized. - Feature2 (Rebase):
Rebasing provided a linear history, stacking the commits on top of the latestdevchanges and removing intermediate merge commits. This made the timeline cleaner and easier to read. - Feature3 (Squash):
After squashing, only one commit represented the entire feature, providing a concise and professional commit history that would be ideal for production logs. - Hotfix (Cherry-Pick):
The single commit from thehotfixbranch was applied directly tomainand then propagated todev, demonstrating selective integration of urgent fixes without merging unrelated work.
- Merge:
Best for integrating collaborative work where multiple developers contribute to the same branch. It preserves context and avoids rewriting shared history. - Rebase:
Useful for local, personal branches before merging into shared branches. It keeps the history linear and clean but should be avoided on public/shared branches to prevent confusion. - Squash:
Ideal before merging a long-running feature branch intodevormain, as it condenses noisy intermediate commits into a single, meaningful one. - Cherry-Pick:
Appropriate when a critical bug fix or small improvement from another branch needs to be applied selectively without merging the entire branch.
All merges, rebases, and cherry-picks were completed successfully with manual conflict resolutions where needed.
After each integration step, all tests passed, confirming that the dev branch now contains:
- The Quit feature (
feature1) - The Max Attempts/Game Over feature (
feature2) - The Hint System feature (
feature3) - The Random Number Hotfix
Conclusion:
The final dev branch represents a clean, stable, and production-ready state.
Through this assignment, multiple Git integration strategies were practiced in a realistic workflow, demonstrating proficiency in managing complex branching scenarios, conflict handling, and maintaining an organized project history.