git reverse cherrypick - ruby-on-rails

My question is, is there a way to mark a specific commit(s) so that either it won't be merged into another branch, or it will be ignored when I issue a "git push" or fetch from another repository?
My understanding is that you can cherry-pick specific commits to merge into the current branch; is there some way to mark a commit as 'local' to a specific machine/repository/branch?
The problem this question grew out of, I am currently solving a different way. Specifically, there is a specific version of sqlite3-ruby (1.2.5) that I require to work on a Rails application on one OSX machine to which I don't have root access. Right now I've made the commit to specify the version in the Gemfile on a local branch called "mac-bundle", and my plan is simply to switch to that branch and merge necessary changes before I run bundle if I need to install a ruby gem.
Which is a minor but live-withable annoyance. It seems possible that a similar situation might arise where the same workaround won't be quite as acceptable, so I thought I would ask for ideas on a different solution.
(Question similar to this one: Committing Machine Specific Configuration Files , and my current solution is similar to Greg Hewgill's answer.)

No, there is not a way to mark a commit as "not to be included in merges". Using separate branches is pretty much as close as it gets.

No, you can't. You can however "fake a commit" on a particular branch.
To do that, you can
git merge OtherBranchName --no-commit
This applies the changes and leaves it in the index for you to take action. Then, you can manually remove the changes applied and commit.
Git then thinks that commit has been applied on this branch, and you both live happily thereafter.
However, this might be ok as a one off, specifically to deal with configuration files. But you should not make this a general practice.

Related

TFS without any branch

Do you really need a Branch to CheckIn / CheckOut Code in TFS i.e, just add files to a folder ?
What would be advantage to Branch in that case ?
You do not need a branch to check in and check out.
Branches however provide you with the ability to make changes to more thank one version of your code at once. Lets say that you have one folder at $/ProjectA/MyAwesomeApplication/Master. You can happily work away, checking in and releasing. At some point you find a bug in production that needs fixed immediately. However MASTER is well beyond what was last released and you don't want to deploy those changes yet.
You know which build is deployed and thus which changeset. You can branch MASTER at that changeset (the past) and create $/ProjectA/MyApplication/QuickFix. There you can fix that bug and ship, then merge back into MASTER and delete that branch.
Now obviously this is expensive and time consuming. A better way would to move forward and just ship what is in MASTER. If you have feature flags and good testing them you should be able to do that. There are however always those exceptions to that rule, and that's where branching comes in.
If you are using Git in TFS rather than TFVC the story is different.

Applying git patches from one repo to another similar structured repo

We have 2 projects, one in rails 2.3.14 and one in rails 3.2.9, we moved the files and changed the structure a bit manually when creating the 3.2.9 repository and now, a few weeks later i want to add all the original repo missing commits to the new repo.
Tried using git format-patch to do it, but since we changed the structure a bit in the new project none of the patches actually applies and returns an error.
Is there a way to do it rather than manually?
try to apply it in the new repo at a revision BEFORE you changed the structure. then merge the new branch into master
Eventually we came to the inevitable conclusion that we have no other option but to merge those changes manually - we exported a patch list from the commits diff and merged the manually one by one, applying the changes in the right places.
Tip for the rest of you: merge frequently if you ever do something like this. applying 533 patches is not a fun thing to do.

pull changes from branch when deleting files

I can't figure out the best way to do this and it has happened a few times where I mess myself up that it'd be nice to know a possible good way for this. On master, I have our main project. We finally got approved to use ARC in iOS and I created a new branch for that to not mess with the main working master branch. I also took the time to delete some unneeded files in my ARCBranch. What I want to do is use this branch for development for the next release. I'd like to pull in the changes from master to the ARCBranch. So I switched to ARCBranch, and did
git pull origin master
I got conflicts, some which were straightforward because I could see the code, others being changes in the pbxproj file where I cannot tell what's what. I did see
<<< HEAD ==== >>>. I can't tell what I need to do here. I can't open it in Xcode, only a text editor. I tried just deleting those <<< === >>> characters since I saw one person on SO say that you typically want both changes and that you could always do that. This didn't work for me. I was wondering if there is a better way to do this change. Maybe somewhere where I can see each change by change happen? Thanks.
Instead, you could try
git rebase master
This would apply the changes commit by commit. If there are conflicts, it would stop there, so that you can resolve them and do
git rebase --continue
to finish applying all the patches.
It failed to auto merge so it marks the conflicting blocks of code and leaves them both so you can decide and remove one yourself.

Git workflow for a small team of developers and designers

I'm getting lost with Git branching model and the workflow that I want to create for my team (developers + designers).
Suppose that the project is based on a MVC pattern, so we have a structure similar to :
Models/
Controllers/
Views/
Developers works on the M & C parts with some basic/generated views (Rails, Django or CakePHP app for example)
and Designers works on the V part
How can I manage that developers works on M&C and keep some basic crappy views, and in the same time, designers make sexy views based on controllers actions coded and added by developers progressively ?
I tried to make it works with 3 branches :
master (production-ready)
dev
ui
but no idea how a designer working on ui branch can keep the code elsewhere than /views updated an a working app...
Thanks folks for help !
With git, there's no reason for developers to work on a separate branch or to have mocked up views. Have designers and developers work in the same branch, on the same codebase. When a view is done (or at least improved and not crashing) have the designer commit and push them to a master repository. The same is true for developers: when a local change is 'done', have them commit it and push it.
Before pushing, each side needs to pull (to ensure there are no conflicts). If the two groups are working in mutually-exclusive pieces of code (separate files or even separate parts of the same files), then the pull will simply update the local copy and all will work well.
With this, both sides are always seeing the most up-to-date codebase, and contributing directly towards the exact end goal, watching it evolve.
Git is so simple to use, theres no reason everyone should not have their own branch to work out of. Hell, thats one of the main reasons to use a version control system. In Git, commits are cheap.
Typically, we have a master, and anyone who is working on updates or features will branch from the master and branch a branch if need be, then a release master (someone like me) will take care of merging them all back down, checking for conflicts, testing the release and merging back to master.
As you work on it, others can receive your changes by doing a fetch/pull against your branch to pull in the changes.
Git isn't magic. It doesn't let your designers use code that the developers are actively writing. The developers still have to write, test and commit their code, and push it some place the developers can pull it from.
Typically you'll have a "bare" repository that all parties push their work to when it's ready to be shared. Everybody else pulls that work down. It might be the designers job to pull the developer's work and merge the dev branch into the ui branch, for example:
git checkout ui
git fetch
git merge dev
If you really want to enforce things like branch and path rights, I suggest you checkout gitolite
This will allow you to manage access at all sorts of levels.

Sharing code between two or more rails apps... alternatives to git submodules?

We have two separate rails_app, foo/ and bar/ (separate for good reason). They both depend on some models, etc. in a common/ folder, currently parallel to foo and bar.
Our current svn setup uses svn:externals to share common/. This weekend we wanted to try out git. After much research, it appears that the "kosher" way to solve this is using git submodule. We got that working after separating foo,bar,common into separate repositories, but then realized all the strings attached:
Always commit the submodule before committing the parent.
Always push the submodule before pushing the parent.
Make sure that the submodule's HEAD points to a branch before committing to it. (If you're a bash user, I recommend using git-completion to put the current branch name in your prompt.)
Always run 'git submodule update' after switching branches or pulling changes.
All these gotchas complicate things further than add,commit,push. We're looking for simpler ways to share common in git. This guy seems to have success using the git subtree extension, but that deviates from standard gitand still doesn't look that simple.
Is this the best we can do given our project structure? I don't know enough about rails plugins/engines, but that seems like a possible RoR-ish way to share libraries.
Thanks in advance.
I think that the git submodule system have a great advantage over svn:externals or symbolic links (and it is also that makes them more difficult to use): the actual submodule version is stored for each superproject version. So is is quite safe to make changes in the submodule that breaks backward-compatibility: it will be possible to checkout any version of the superproject(s) with the proper submodule version, because the superproject will contain a reference to the proper submodule code. You may also maintain two branches of the submodule (v1.0.x and v2.0.x, for example) and use different branches in different projects without a problem.
So I think it is really worth to use submodules even if they are a bit complicated. Git 1.7 has some major improvements on this area, for example git status now indicates the uncommitted modifications in submodules, so you probably don't forget to commit submodules first. A good GUI may also be a help (I have a small pet project about this, see here).
If you really don't want to care about submodule versions (you never make backward-incompatibile changes in the common code) then I also suggest using symbolic links. Although committing and fetching won't be much easier than for a submodule...
I tend to prefer symbolic links to submodules.
1) Have foo, bar, and the common code (common) in 3 separate repos.
2) In directory for foo, add a symbolic link to common, where necessary.
$ cd foo
$ ln -s /path/to/common lib/common
3) Check in the link.
$ git add lib/common
$ git commit
4) Repeat for bar
This takes advantage of the fact that git respects symbolic links and stores the location of the target (as opposed to following the link.)
Ofcourse, the expectation is for you to consistently use the same target path for common. I work around this by not checking in the symlink, and adding a README.setup file in each of my projects reminding me to add the requisite symlinks upon initialization. Having a devsetup.sh that does this sort of initialization is useful here too.
IMO, this is much nicer to deal with than submodules.
A Plugin is totally the way to go, and if you end up using it on more than two projects or would be useful to the general public, probably worth the effort to make it into making it a gem.
Here is a good resource on the subject
http://nubyonrails.com/articles/the-complete-guide-to-rails-plugins-part-i
and more importantly ...
http://nubyonrails.com/articles/the-complete-guide-to-rails-plugins-part-ii
In the end you will have three git repositories one for foo, one for bar and one for the plugin.
Then in each project to keep it upto data you will be able to do
./script/plugin install --force git://github.com/path/to/plugin/repository
to keep it upto date.
Good luck!
-- jonathan
Git subtree is a part of GIT since 1.7.11 and I wrote an article about sharing code between Rails applications: http://igor-alexandrov.github.com/blog/2013/03/28/using-git-subtree-to-share-code-between-rails-applications
In short: yes git-subtree works and works great!
If you're looking at making a plugin, you should also consider making a gem. They are very similar in terms of using them, but gems tend to be easier to work with, support dependency management, and are easier to share/distribute with the community.
Ryan Bates of Railscast has a great tutorial video about making a gem that you can find here: http://railscasts.com/episodes/135-making-a-gem
You could create a repository with the common code and clone it twice. Both clones would become foo and bar. You could still develop the common code in separate branches in both projects and push that branch to the common code repository. To update the common code in the projects you would just merge the common branch into the master branches of foo and bar.
UPDATE: You can imagine this as a single repository with three branches: common, foo and bar. You would have the common code in the common branch and add the project specific code only to the foo or bar branches. Now you could clone this repository twice as foo and bar and delete one branch from both of them (branch foo from bar repository and branch bar from foo repository). Then you would delete both foo and bar from the first repository. This would become the common repository. The final result would be the same as above.
The best thing you can do is to create a plugin for your common libraries, or even a gem, that way you have a nice way to update/distribute it.

Resources