The transition from CVS (Fall 2011) was discussed in bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=349695
- http://www.youtube.com/user/cdtdoug (CDT screencasts - last 7 videos are about GIT)
- Working with CDT and git -- How to check out the CDT source code with git
- http://wiki.eclipse.org/EGit/User_Guide - much improved; highly recommended
- http://veerasundar.com/blog/2011/06/git-tutorial-getting-started/ - nice beginning tutorial esp. describing local vs. remote repository and a nice diagram of Git Data Transport Commands
Things I Used To Be Able To Do Using CVS
Here are some things that I used to be able to do using CVS, but are either difficult or I can't work out how to do them using Git/EGit
Managing Two Branches
Say I had two branches A and B. If I added a new file (plugin, whatever) to branch A, I'd just commit it then switch over to branch B (I might have two workspaces set up, one with branch A and one with branch B). The I'd use Team>Compare With>Another Branch or Version... and add/replace any changes. Then I'd commit to branch B.
Using EGit, I need to show the history view in branch B then cherry pick the change from branch A I want (assuming it shows in the view, which sometimes it doesn't seem to). The problem with this it that you need the file to exist in the target branch before you can show it in the history view. How do you do it when a new file is added?
Answer: Select the folder or package that should contain the new file and select the history view. In the history view, select "Show All Branches and Tags" (blue arrow icon at top right) and cherry pick as usual.
If I had some uncommitted changes in my workspace, I could just say Team>Create Patch... to save a patch of the changes. In EGit, it seems you have to commit the changes first. How do I create a patch without committing changes?
Answer: It seems you cannot. I would suggest to commit the change in a temporary/feature branch.
- Team->Switch To->New Branch
If I had a changed file in the workspace, I could just revert it using Replace With... For EGit I don't always get the option? What gives?
Feedback: In what cases does it not work?
Switching to a different branch
Each repository that you clone can have one or more branches in that repository that is stored on your workstation. (e.g. master and ptp_5_0 are kept by most of our PTP developers). If you have two different workspaces for the two branches, then switching one to a branch will switch the other one too. We recommend making two different clones of the git repo, where one by default points to master, and the other points to ptp_5_0, even though they both contain both branches.
Then to switch ...
- Select Team > Switch To... and select a branch name from the list
If there are too many branches the list does not show all of them. In this case
- Select Team > Switch To... > Other...
- On the dialog, select a branch, a tag or a Reference
- Under 'Local' you should see the list of branches that you included when you originally cloned the repo. The current one is checked. Choose the one you want to switch to.
- Click Checkout button
Question: my git repo has master and ptp_5_0 in it that i selected when i cloned the repo. Where do I see what these are (branches that are in my cloned repo)
- Answer: in the Git Repositories Perspective, under the node for the repo in the Big Repositories view, open Branches/Local and you will see the list.
Question: what if a branch was added after I cloned my repo or I forgot to select a branch I meant to clone?
- Answer: In your Project/Package Explorer view right click on any project from the repo, and select Team -> Switch To -> Other. Select the desired branch (often this is the latest one under remote tracking). Instead of hitting 'Checkout' hit 'New Branch'. This should create a new local branch tied to the remote which will operate as expected.
Question: what happens to changes you have made to files in your workspace (not committed or pushed) if you switch to another branch?
Adding a new PTP project to git
- Rightmouse on project in Package Explorer, Team > Share Project...
- Select Repository type, Git
- In Configure Git Repository dialog,
- select the repository to add the project to
- working directory will thus be selected
- Path within repository: select the correct part within the PTP repo here
- (do other projects too if necessary)
- Team>Pull (to make sure the rest of your repo is up to date)
- Team>Push to upstream (I think you can omit this since it's done at the end too.)
- When you have added all projects to the repo,
- Team>Commit and enter commit comment
- Team > Push to upstream
Other Questions I Have About EGit
I try to compare my local copy of branch A using Compare With>Branch, Tag, or Reference... then selecting origin/branch B from Remote Tracking. However it doesn't show all the changes even though I know they are there. Why is that?
Answer: The most likely reason is that you didn't push (for local changes) or pull (for remote changes). If these changes were made locally and you have committed them but not pushed yet than the changes are only in the local branch B not the remote tracking branch B. In that case you should compare to the local branch B or push before you compare. If the changes were done remote (in a different repository) you need to pull (or fetch) to update the remote tracking branch to the new version. The history view helps visualizing to which version each branch points.
Comparing your version with HEAD ... or ...
Note that you need to "Fetch" first...
- Team>Fetch from upstream
- this updates your local repository but not the files in your workspace
- To compare an entire project or part of a project, Rightmouse one project or container that you want to compare with e.g. master's HEAD; to compare a specific file, Rightmouse that file
- Compare With > Branch, Tag or Reference
- In the Compare Dialog, Under Remote Tracking, choose the branch you want to compare with, e.g. origin/master
- The 'Git Tree Compare' view appears, with a tree of the changes.
- If you did the "Compare With" on a single file, the diff viewer appears automatically above the History view.
- Double-clicking on a file brings up a diff viewer.
- Be sure to 'Pull' when you are done to completely update your working directory(workspace) to match the local repository you got via the 'Fetch'
Are new or deleted files not shown? The Git Tree Compare view seems to show just changed files.
TBD: Define "Cherry Picking"
If I cherry pick some changes from one branch to another, do I need to commit it? Or is it just done? How do I revert it if need to?
How do I only apply some of the changes from a particular commit? Cherry picking only seems to apply them all.
Answer: Cherry picking a commit automatically commits it to the destination branch (adds a commit with the same commit message). So reverting this commit is the same as reverting any other commit (see below).
Applying only part of a commit is more difficult. In this case, you will need to either apply the changes without cherry picking or cherry pick and reverse the changes not needed. (Note that git works best if commits are small and frequent, with each commit representing a single "logical" change, which may span any number of files.)
After cherry picking, you can right-click on the project and select 'Compare With...' -> 'Previous Revision' to open a Git Tree Compare view and undo any unwanted changes. Then commit these changes with "Amend Previous Commit" selected, so that the cherry pick and these changes are all contained in a single commit.
There are two ways to revert commits in git. You can either add a new commit that reverts a previous commit, or you can tell git to reset the branch to a prior commit. The former is much safer, since it functions like any other commit and does not change the revision history prior to the commit. Also, this will only revert the selected commit. The latter operation, however, will erase all trace of all commits after a selected commit. This can be useful for commits that were made in error. However, you should never reset commits that are already pushed to remote. Only use this for recent commits made in your local workspace. Otherwise, you will not be able to push your changes to remote, since our remote server is configured to not allow modifications to history.
To undo commits, select a commit in the history view and right-click. Selecting 'Revert Commit' does the safer option described above. Selecting 'Reset' -> 'Hard' does the unsafe method and will erase all commits after the selected commit.
Committing and Merging
(Note: we recommend having one workspace for ptp_5_0 branch, and a different workspace for master)
Changes to both ptp_6_0 and master
Simple case: For committing changes to both ptp_6_0 and master we use the following policy:
- All changes which should go both into ptp_6_0 and master should be first committed to ptp_60
- In ptp_6_0 branch, do Team>Push to Upstream - do this on any file, it pushes everything in your local repo up to the remote repo
- After commit and push to ptp_6_0, merge the changes into master:
- In master branch, do Team->Merge...
- In the Merge dialog, select the branch to merge from (e.g. under Remote tracking, choose origin/ptp_6_0) and select the "Merge" button
- Then do Team>Push to Upstream to push the merge up to the remote repo
- To Be Determined: if you find conflicts due to a commit from another developer, what do we do?
More Complicated cases
- If a conflict occurs in doing the Merge, see Resolving a merge conflict
- Any change in ptp_5_0 which should not go into master has to be reverted in master. This should be done immediately to not be forgotten.
- First ptp_5_0 has to be merged into master and then the one commit, which should not go into master, has to be reverted (using History View->Right Click->Revert Commit)
- This may fail if the revert is too complicated, in which case one of the following must be used
- If all changes in ptp_5_0 since the last commit should be reverted, it's easier to use "git merge -s ours origin/ptp_5_0" from the command line
- To see all the changes that would be discarded, use "git log ..origin/ptp_5_0" (the ".." is not a typo)
- To Be Determined: what to do if you don't have command-line git
- If you manually merge the changes and they end up being empty, you'll need to use "git commit --allow-empty" from the command line as Egit can't handle this
- Cherry pick can be used if either a change has been accidentally first pushed to master, or if a commit should also go into ptp_4_1 (whether first committing it to 4_1 or 5_0 doesn't matter)
How to merge changes from a different branch when using a different workspace for each?
Answer: The easiest option is to push from one workspace and pull from the other. It is also possible to setup the other workspace repository as a remote repository to be able to directly fetch.
More information about the merging strategy:
External information to do the individual steps:
- Commit: http://wiki.eclipse.org/EGit/User_Guide#Committing_Changes
- Merge: http://wiki.eclipse.org/EGit/User_Guide#Merging
- Revert Commit: http://wiki.eclipse.org/EGit/User_Guide#Reverting_changes_introduced_by_a_specific_commit
- Cherry Pick: http://wiki.eclipse.org/EGit/User_Guide#Cherry_Picking
- Setting up other workspace as "remote" repository: http://wiki.eclipse.org/EGit/User_Guide#Adding_a_Remote_Configuration
If I cherry pick some changes my local workspace seems to be in some kind of merged state (e.g. [org.eclipse.ptp|Merged master]). If I commit, EGit forces me to commit all changes in the workspace, not just the ones I select. I may have changes that I don't want to commit right now. What do I do?
Answer: A merge conflict can occur if both the current branch and the cherry-picked branch have made conflicting changes since they diverged (since their last common commit). This can be resolved using the merge tool, as described in the EGit User Guide.
You should avoid cherry-picking into a branch that has been changed since its last commit, because you then will have to deal with changes coming from two difference sources (the original changes and the changes introduced by the cherry pick). The "git stash" command is useful for handling this case, but it is not yet available in EGit. It allows you to set aside work that has not yet been committed. From the command line, "git stash" will "stash" all changes since the previous commit. You can then work on a different commit, such as cherry picking from another branch. Once you have committed those changes, the command "git stash pop" restores the previous changes.
Yes, it seems that once a merge conflict is resolved, EGit no longer allows you to select individual files to commit. More details to follow...
- In CVS, HEAD means the 'branch' that is the latest most recent main work
- In GIT, HEAD is the endpoint of a branch. 'master' is the 'branch' that is the latest most recent main work
- So, there is a HEAD revision of each branch, which is the endpoint (last change).
- E.g. there is the HEAD of master and the HEAD of ptp_5_0
- In GIT, HEAD is the endpoint of a branch. 'master' is the 'branch' that is the latest most recent main work
- 'Origin' is the default name of the remote repository on eclipse.org