I need to push a commit into two or more branches as the same time, using Git and Netbeans. Those branches are not local, but in BitBucket and shared with others developers.
The situation is this:
We have a branch which is used as a master (soon we will rebase it) and we are working on an another one. WHen I find a problem on the older branch, I'll switch to that and do the modification, then commit. I want the pushed code to be merged also with the newer branch.
How Can I do ?
There are a couple of ways to approach this, sounds to me like the simplest one in this case might be to use git cherry-pick to copy the commit from old-branch to new-branch locally on your machine, then push the revised new-branch back to Bitbucket.
The alternative way would be to create a PR on the server from old-branch to new-branch, whether or not this is viable will depend on what else is in old-branch that you don't want to copy across.
Thanks to all. I tryed a cherry-pick trough Netbeans git plugin and it worked perfectly. Now just have to guess if it add only committed lines or if it merges the entire files in the pick. I'll do some tests. I'll try also the pull request, sooner or later.
Related
I am working on a branch (feature01) and it is still work in progress. Now I have to leave the WIP branch and start working on another feature/bugfix and for that, I have to create a new branch out of my development branch. I usually stash all the changes in feature01 and start working on a new branch. I don't like this solution that much as I can be working on the new branch for a day or so and I have to remember that there is something on the stash. Is there any localized version of stash for each branch or something of that sort so that I can move around between different WIP branches without having to stash a bunch of stuff and keeping track of them manually.
One solution I was thinking of was committing the local changes before checking out to a new branch and then later when the work is done on one of the WIP branch, I can squash some of the commits together with a more meaningful message rather than having a bunch of commits with not so helpful messages.
I would like to know if you guys know better solutions to this problem or if this problem is arising because my git workflow is not correct. I searched for solutions online but most people recommend stashing which I don't like much when the changes stay for a longer time in the stash.
Cheers.
Waqar
I'd suggest using a temporary commit :
# you have unfinished modifications to save before switching
git commit -am "temp - DO NOT PUSH"
git checkout other-branch
Then you can work on the other-branch, and when you're done, it's easy to undo the commit on previous-branch while keeping its contents
git checkout previous-branch
git reset HEAD^
Of course, it's easier when you have aliases
git config --global alias.ct 'commit -am "temp - DO NOT PUSH"'
git config --global alias.rs1 'reset HEAD^'
Then just
# to save uncommited changes ON the branch
git ct
# to "unravel" a temp commit
git rs1
Instead of stashing or doing a temporary commit, another solution is to use the git worktree feature to work in another folder (but still within the same repository).
A blog post on the subject: https://spin.atomicobject.com/2016/06/26/parallelize-development-git-worktrees/
Git uses commit id's such us 521747298a3790fde1710f3aa2d03b55020575aa.
This hashcode keeps every changes in your code. if you want to change your branch without commit, its not logical according to git rules. Every changes must be marked with this hashcode. To extend you can choose which commits must be push.
We are currently 2 people working on a project. We use github, we have one master branch. And 2 sub branches for each developer. So in total we have 3 branches with master.
Lets say we have a file hello.class. Both developer makes changes to the file in their respective branches. If I now push and merge my sub-branch with master. The other sub-branch falls behind and needs to pull master, and then rebase it with hes sub-branch.
The problem now occours, because if he rebase's masters changes, he overwrites he's work in hello.class. How would we go about solving this problem? Is there a way to pull master, and then automerge changes into the sub-branch without overwriting the work done in the file?
Merging is half of what git is for. If the changes conflict, git will abort the merge/rebase and ask you to fix them up before continuing; if the changes are in different parts of the file, git will do the merge itself. You have to go out of your way to lose work.
Git doesn't overwrite changes. It merges them when you do a rebase (you could also do a merge, i.e. git merge master). If you both change the same line of code then git will get confused and ask you to fix merge conflicts. But if you didn't change the exact same line, git is smart enough to merge the changes.
I'm assuming that you are committing .java files as you shouldn't be committing .class files.
This may be a stupid question, but after several times trying to get this right I'm getting frustrated. I want to use github to host my project, we are 2 people working on the project and the aim was to share the work. And help each other.
I managed to create the resepetory, and committing to master branch. If the other guy deletes the whole project he gets the latest updates, but I'm sure this is not the way its supposed to work.
Lets say I commmit a new class file. I commit this file, how could the other person download this file? We've tried pull, synchronize etc etc without any luck. The only way we have found to give him "my" latest updates is for him to delete all content and make the project from scratch.
What am I missing? How can we synchronize workspaces? So I can see and download his changes when i open Eclipse? (We are not working in the same class). So really all I want to do is download he's latest commits.
EDIT : My solution was that my partner was working in a copy of the local git workspace. So instead of modifying the local repo he was modifying a copy of it inside the Eclipse workspace. And because of this nothing updated when he did the pull. I also switched from Egit to GitHub command line tool, and I'm in love. Thanks everyone :)
Normally with GitHub, all of what you have described works perfectly, I have not had any kind of similar problems.
One thing about git, a commit is a bit different than a commit in SVN. With git, you use push and pull to interact with your remote repository.
I am not sure what you mean when you say:
If the other guy deletes the whole project he gets the latest updates,
but I'm sure this is not the way its supposed to work.
That being said, I have never used Egit, I prefer to stick to the command line for all my git needs. I have had issues with other software (Sublime Text 2) where I would have to exit the editor, then run all my commits and other git actions. I do not know how well Eclipse plays with git in general.
Try to have your partner run git remote -v just to make sure he is tracking the repo properly. Also, do you know if he set up an SSH key for GitHub, or you sending your pushes and pulls via https?
Keep in mind this is pretty hard thing to help you out with since I am not sitting at your computer. GitHub Help has some very good walkthroughs on setting up git and remote repositories.
Also, I highly recommend the time to go through CodeSchool intro to git. If this is your first time using Git, this is the best starting point.
There are much more complicated scenarios, but basically, you need to "push" your commits to the upstream, and pull your colleague's.
Clone the repo. By cloning it you will guarantee that it has an "origin", the github remote. You make changes in your local repo, committing them as you go. When you are at a milestone, use Team > Push to push all of your commits to github. Your colleague will pull them, as described below.
When you try to push, you may discover that your colleague has pushed changes and that git will not allow you to push until you merge. Try Team > Pull which will merge the remote changes into your local repo. If there are no conflicts, you can now push. If there are conflicts, fix them and then commit. Then push.
This is a substantial simplification but may get you started. The main point is that the equivalent of a SVN commit is, in git, two, maybe three, operations: add, commit, push. Git pull is vaguely analogous to SVN checkout.
Take a day to read up on git. There's great documentation at GitHub. Once you get the hang of it, you'll love it.
When using git to collaborate on a project, you are managing both a local and remote repository. When you commit, you are only saving changes to your local repository. After committing, you need to do a push in order for your changes to be saved to your remote repository. After doing that, if your collaborator does a pull he will get your changes.
My understanding of git add is that you're basically saying to your local git repo "Yes, I'm sure I want to make these changes."
My understanding of git commit is to actually save the changes to your local HEAD branch. At this point they are actually in version control, but are only local to your instance of git.
My understanding of git push is to propagate your saved (committed) changes to the master repo, so other developers (or perhaps a CI build) can pull them down for themselves.
If anything that I have said so far is wrong or is misleading, please begin by correcting me. Assuming I'm correct in my understandings, I originally had a package in my Java project that looked like this:
com.myapp.server.servlets
FizzServlet
BuzzServlet
But then I decided to refactor the names and of a few things, as well as both adding & deleting some new files/packages:
com.myapp.server.servlet
FizzesServlet
WidgetServlet
com.myapp.server.servlet.impl
FizzesServletImpl
WidgetServletImpl
Overall, I account for 5 changes to this directory:
Changed the name from "com.myapp.server.servlets" to "com.myapp.server.servlet"
Changed the name from "FizzServlet" to "FizzesServlet"
Deleted the BuzzServlet altogether
Added a new WidgetServlet
Added a new com.myapp.server.servlet.impl package with two child files
Do I have to do any sort of special command magic here, because I did so much refactoring, or can I just run something like git push * to push everything to GitHub? In the SVN Eclipse plugin, if I renamed a package or source file, and then tried committing that change, I would often lose the file altogether (locally) and have to restore from local history. Even then, I got burned far too many times to count and lost a lot of work. I'm hoping not to get the same experience with Git.
From the way you're very careful about pushing, your understanding of git push is not quite complete. push will literally only push your commits to your remote -- that means, it will copy the exact state that you saved in the commit(s) you have made since last pushing. In Git, every commit is a snapshot of all the files in a repository (it does in fact record all files, and not just the changes). So what you see locally after committing will be exactly what's copied onto the remote when pushing.
When you push, one of two things can happen:
The push succeeds, in which case all is well and the state of the remote mirrors the state of your local repo (to emphasize this, remember that git commits are identified by their SHA hash -- if the commit were different, so would the hash be)
The push gets rejected, because it is not fast forward. This happens when someone else has pushed commits onto your remote since your last pull/fetch, and it is the equivalent of the nasty and oft-feared conflict when trying to commit in SVN. However, your local state is not affected by this. You will have to resolve the conflict (a) dropping your commits and accepting the state of the remote (git reset is used for this) or by fetching from the remote and (b) merging your local changes, thereby creating a merge commit which will indicate the diverging and re-converging of your history, or alternatively (c) rebasing onto the remote, to produce linear history.
The conflict resolution case will take a bit more looking into, but the actions required are well-described in the Pro Git book (chapters Branching, Merging, Rebasing).
A conflict can only happen if someone else can push to your remote, or if you push to your remote from another computer. If you are working in a single-user single-computer scenario (at least for now), there will be no conflict when pushing.
I'm using Subclipse 1.6x plugin in Eclipse. Let me explain the scenario first:
Say I have the trunk of my project with revisions r1 to r100.
At revision r100 I created a branch and started committing say r101 to r105.
At this point, I thought I will bring in any changes from trunk so that my branch is updated.
But due to a merging mistake, I end up merging r80 from trunk to my branch and committed it as revision r106. So I revert my change in r106 in the branch and do another commit r107 to this branch.
During this time there has been commits say r108 and r 109 in the trunk.
Now after reverting my bad commit in r106, I correctly bring in all changes from trunk until r109 to my branch (by merging) so that my branch is up to date, and commits this to my branch as r110.
All is good. Now I decided I don't need the branch so let me merge all changes in branch (r110) back to trunk. So after this merge all I should see is the changes I made in the branch (revisions r 101 and later in that branch) as my branch is up to date with trunk.
I do a Team -> Merge with From url as trunk and To url as my branch path. The From revision is the last merged revision in trunk (r109) and the To revision used is the latest in my branch (r110). I tried a Dry Run and also creating a Unified Diff file option in the Merge window. Both of them looks correct and the only updated files are those I changed in my branch.
Now I run the Merge and and the merge result is different from Dry Run. First it correctly merges files shown by Dry Run (which is what I expected). But it doesn't stop there. It then tries something like this:
--- Merging r80 through r110 (May be because of my wrong merge in the branch???)
and then does something like:
--- Reverse-merging r110 through r80.
The end result was merging in all my changes exactly as the Dry Run result plus a lot updates/changes to other files (due to second Merging and reverse-merging I guess).
Any thoughts on why this might be happening and how to make the merge result correct/same as the Dry Run result? Even the Unified diff file created is correct.
Thanks for reading through the lengthy post.
The Subclipse merge dialog has not been worked on since before Subversion 1.5 and the introduction of merge tracking. I would suggest you install the CollabNet Merge Client plugin that is included on the Subclipse update site and see if you get the same results.
The Team > Merge option should bring up a wizard if this client is installed.
Ok I figured this out or at least solved it for my case. The issue was because on my branch I wrongly merged r80 from trunk and committed as r106. Then I did Team > Revert > last commit to revert this merge-commit and checked this as a new commit r107.
There are 2 issues with this. First this is not the best way to revert a merge commit in SVN. Google for more details.
Second issue is when you merge these changes (in multiple commits) back to trunk, SVN will try to apply each commit one by one to the trunk. As I messed up r106 on branch by merging r80, SVN gets confused about the change because of conflicting ancestry for the files. In order to avoid this, and to tell SVN don't worry about the ancestry but just merge the differences/changes in my branch to trunk, check the "Ignore ancestry" option in the Merge window. This took care of the problem for me.
Also as a side note, in SVN merge, the result of Dry Run is equivalent to running Diff between the files. But when you do the Merge, it will look into the ancestry of the file and brings in each commit one by one to do the Merge. Hence the results may not always be the same. There is more details on this in SVN documentation.
This is what I understood from my experience and am posting this here as answer as I didn't get any other responses to my post. Please add any comments if I'm not fully correct.