Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
ToxicFrog
Apr 26, 2008


chips posted:

One thing I haven't been able to work out with git (or it might just be git svn) is how to determine and change what a branch is tracking remotely. It doesn't seem to be in .git/config, and I can't find any mention of it.

In plain git, it's in .git/config:
code:
[remote "origin"]
        url = git://orias/git/lua.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
[branch "test"]
        remote = origin
        merge = refs/heads/master
Here, both "master" and "test" are set up to track remote branch origin/master.

If git-svn does something weird here, I don't know, sorry.

Adbot
ADBOT LOVES YOU

ToxicFrog
Apr 26, 2008


Sizzlechest posted:

It is you who doesn't understand how distributed vcs works. Distributed version control has a workflow, otherwise changes would never get up the chain to be released. The workflow relies on individuals collecting changes from people they trust and pass them on to people higher up the chain who trust them. It's extremely flexible and powerful for large open source projects like the Linux kernel and is completely useless for the OP's needs.

You seem to be conflating "distributed version control software" and "distributed kernel-style workflow". DVCSes are, as a rule, versatile; you can organize your project, but you are not required to.

For example, last semester, I used git for a few group projects. The actual workflow was similar to how we would use a centralized VCS - there was a central reference repository which everyone pushed to and pulled from, with master representing the definitive state of the project.

Why didn't we just use SVN, you ask? Because git took us all of thirty seconds to set up, and furthermore supports tags, branches, private branching, offline commits, and stashing, to name just a few features we all made heavy use of, and svn does not.

The fact of the matter is, if you want an svn-like workflow with a central repository that everyone talks to, you can do that with a DVCS - while at the same time gaining access to a host of useful features that centralied VCSes simply do not have. Saying "distributed version control is a bad fit for this project because they don't want to use linux-kernel-dev style workflow" borders on the nonsensical.

ToxicFrog
Apr 26, 2008


Mithaldu posted:

I don't even know what this is supposed to mean.
Oh no. I have to make the massive and completely unwarranted effort of stashing things. :qq:

If you don't have an editor which can easily deal with all three line ending styles, or cannot set it to automatically transform all files to unix-style or don't even do that then you can walk off a cliff for all i care.

As such, i never even noticed this being a problem at all.

The problem he refers to is not with the editor, but with git itself. It's possible to get into a situation where the following happens:

- you check out a commit
- git fucks up with the CRLF conversion somewhere
- now git thinks all your files are modified because the line endings differ
- you can't switch branches or anything because git thinks everything is modified even though it isn't

Personally, I haven't observed this behaviour recently, but then, I haven't used git on windows recently either.

ToxicFrog
Apr 26, 2008


stash/reset might work if you realize what's happened immediately; however (at least back when this happened to me) the more common case was checkout, hack hack hack, status, oh dear it thinks everything is modified. And then you have to disentangle the real changes from the bogus ones before you can stash.

:shrug: These days I do most of my development on linux and all of it using LF linebreaks, so.

ToxicFrog
Apr 26, 2008


Mithaldu posted:

As far as i know (and i could be wrong) the only real way to get a gui frontend like this on git is to run the command line stuff and parse the resulting text. This means that the author has to do a poo poo-ton if matching and many possible combinations and situations that can be easy to overlook.

Correct, and IMO this is one of git's biggest flaws; the lack of a "libgit" that programs can talk to directly makes it harder to write frontends for it relative to other VCSs, which in turn means frontend development for git tends to lag behind, limiting uptake among people who aren't fond of the command line interface.

ToxicFrog
Apr 26, 2008


Yes, with something like
pre:
git checkout master
git tag old-version
git reset --hard new-version
Which will tag the old version so it can be retrieved later, then adjust master to point to the new branch.

This makes pushing master a non-fast-forward and will pretty much require people who have cloned your project to re-clone, though.

ToxicFrog
Apr 26, 2008


ColdPie posted:

I'm not familiar with git-stash, myself. What I'd do is something like:

pre:
git add -p <files with changes you want to keep>
# use the patch interface to add the chunks you want to keep
git commit
git checkout -b wacky_feature
git add <files with ugly changes>
git commit
Then you've got wacky_feature with its ugly commit on top of the experimental branch with its desirable commit.

Note that "git gui" provides a nicer interface for staging individual diff chunks, too.

ToxicFrog
Apr 26, 2008


epswing posted:

Aww dammit, I forgot that you can just point to a folder on a share and blamo. This is what we're going to do for sure, at least for now. Thanks!

This may be a stupid question, but as your background is in linux, what's wrong with just hosting the repos on a linux box running sshd and using hg's SSH support to talk to it?

ToxicFrog
Apr 26, 2008


^^ Yes; both "copy the repo, then use 'git remote' to link it to the original" and "clone the repo locally, then move the clone somewhere else and use 'git remote' to edit the link" will work fine. Git repos are self-contained and all relative paths.

epswing posted:

Nothing's wrong with that plan, except at my new job there isn't a single linux machine in the building.

:negative:

Godspeed. :smith:

ToxicFrog
Apr 26, 2008


^^ Expanding on this, if you rename the file but don't change the contents in the same commit, it always gets it right. If you do change the contents at the same time you renamed it, it guesses, but the more you change the less likely it is to realize it's a rename rather than a delete+create.

ToxicFrog
Apr 26, 2008


:psyduck:

Captain Corny, I have three questions for you.

(1) You say that developing software that only runs (or only runs well) on Linux is a waste of time. Is that true of any OS-specific software? Was all the time MS spent on Visual Studio, or Apple spent on XCode, wasted? Or is it only a waste when they aren't developing for the OS that you prefer?

(2) Why are you writing off the entire concept of DVCS based on a bad experience with one windows build of git? You kind of give the impression that you went into this wanting to dislike git so you could dismiss DVCS as a whole and reassure yourself that by using SVN, you've made the right choice.

(3) As a windows user, why did you decide to start with Git in the first place when even Git diehards like myself agree that Mercurial has better windows support?

ToxicFrog
Apr 26, 2008


ani47 posted:

This is what perforce excels at handling large binary files. For comparison - I've worked on a depot that reached 2TB. Obviously at that size people don't sync to all of it only the parts they need.

Having used P4 extensively at work, the main problems I've observed with it are:
- it's pricey
- it's amazingly slow
- after using git or hg, it feels extremely awkward and dated

That said, it does scale very well and handles binary files fine - it starts out slow but doesn't really get any slower as you add more stuff to it. It's also cross-platform, has both graphical and command line interfaces, and even has a nice Python API. It also has changelists, which don't really replace topic branches but are at least much more pleasant than what you get with, say, SVN.

All in all it's not my favorite version control system, but if you need to control large numbers of large files you could do a lot worse.

ToxicFrog
Apr 26, 2008


lol if you posted:

Can you expand on this? Off the top of my head, things that will cause Perforce slowness are:

:words:

It's probably a combination of #1 and #3, although #1 more on the network side of things than the server itself - I worked at a branch office and the main servers were on the opposite side of the continent. We had a local p4 cache but for some things it's still going to end up hitting the master server. #3 because this is a fairly large company with lots of development activity and everything is versioned.

It wasn't terribly slow by centralized VCS standards, but waiting for a network round trip to the local cache (and sometimes the master server), followed by the transfer of megabytes or even gigabytes of data, for every single operation gets old fast.

In recent years I started just importing the entire clientspec and history I was working on into git and working from there. The initial sync takes a while but it's much more pleasant afterwards.

ToxicFrog
Apr 26, 2008


RyanNotBrian posted:

- Are there tools that work with git that can FTP only the changed files from STAGING to PRODUCTION?

If you're rolling your own you can use git diff --name-only old..new to find out which files changed between commits old and new.

However, a better solution is to have a PRODUCTION that you can access via ssh rather than ftp and use something like rsync, which automatically transfers only changed files.

ToxicFrog
Apr 26, 2008


Rocko Bonaparte posted:

Do you need git installed on a remote machine to use git locally with SSH with the remote space? I know the normal thing to do is to do the git administration on the remote machine--particularly the git init that starts the whole mess. But is it really necessary? Could I set up a .git hierarchy in some directory, and then run all the git operations from my client machine? I don't know what operations git is doing over the SSH link.

You do need git installed on the remote computer (git locally is sshing into the remote and starting git there, then they communicate over the ssh connection).

That said, you can always just mount the remote machine over ssh using sshfs, and then access it with git as though it were a local directory.

E: or have a post-commit hook that rsyncs a local repo to the remote machine

ToxicFrog
Apr 26, 2008


Lysidas posted:

I'd be uneasy about this too. I don't believe Git is designed to work over a network mount like this, and who knows how well the dokan sshfs plugin works.

It works fine over sshfs-in-linux (and nfs, for that matter), but I have no idea how the windows one works.

ToxicFrog
Apr 26, 2008


Suspicious Dish posted:

For something really low-level, you can read Git from the Bottom Up.

I'm also fond of Git for Computer Scientists for a good look at how branches etc work internally without getting sidetracked by implementation details.

ToxicFrog
Apr 26, 2008


Ephphatha posted:

Has anyone managed to get a git server running on a Windows machine, and can you share the magic so I can give it a shot?

It's likely that neither of these is the best option, but you could:
- install cygwin (or msys?) opensshd and just access git over ssh; this doesn't offer the fine-grained control that gitolite does, but if it's a private repo it should tide you over
- install a lightweight linux distro in a VM and run gitolite on that

ToxicFrog
Apr 26, 2008


Rocko Bonaparte posted:

I'm now looking into more rigorous backup strategies. I have some online web storage that takes SSH, but they won't add git. Regardless, is there a way to use scp to at least mirror stuff?

Github is pretty excellent. Furthermore, if you have ssh access to something, you can stick a repository on it even without the ability to install git on it - just mount it using sshfs and create a "local" repository on the remote drive.

Failing that - since it's really a backup you're after, not a mirror - any dumb storage will do; just copy or archive your .git directory.

ToxicFrog
Apr 26, 2008


Rocko Bonaparte posted:

I had actually tried this so maybe I have something else to ask about here. I'm working on Windows here, using Git Extensions. The closest I found to being able to mount sshfs is DokanSSHFS. For simple copy kind of operations it was working fine. However, I couldn't even init a repository with it. Something in the Git Bash with Git Extensions was also getting in the way; it was flipping around path separators and then not finding the path. I have no idea what the deal was there. I imagine you were thinking about mounting sshfs on Linux, but I'm wondering instead if there's a well-vetted method for doing the same on windows.

To be honest, I have no idea. I was rather thinking about doing it on linux; I do none of my development on windows and don't really know if there's a good sshfs implementation for it. There wasn't last time I checked, but that was years ago.

If you're using windows you'll probably have a much easier time either backing it up using dumb storage, or installing git on something you can ssh into and pushing to that.

ToxicFrog
Apr 26, 2008


Nippashish posted:

One of my projects has a module that's rapidly outgrowing the project it's a part of. I'd like to pull it out into its own separate repository, but I'd like to pull its commit history with it.

I'm using git, and unfortunately the commits that affect module3 aren't all together in time (since I've been working on other parts of the project as well) and there are probably at least a few commits that affect files both inside and outside of module3 (since I have horrible discipline).

I'd like to build a new repository and populate it with all of the commits from this repository that touch any files in the module3 subtree. It's okay if this pulls a few extra files along with it since I can clean those out of the new repository by hand, but how do I extract the directory with its commit history?

I have not used it myself, but I'm pretty sure that git filter-branch --subdirectory-filter module3 is what you're after, possibly with --prune-empty as well (although I think --subdirectory-filter makes that unnecessary in this case).

Do that on a clone of the original repo, then delete the original branches from it and the origin remote and you have a new repo containing all of the history, and only the history, of module3, with the contents of module3 as the repo root.

ToxicFrog
Apr 26, 2008


Optimus Prime Ribs posted:

Does that mean anything I add to the stage will remain there, even after I close Git Bash, and be able to safely be commited at some other time? Or could that gently caress something up?

git-bash isn't really a git "session", it's just a command line interface pre-configured to be easy to use git from. Git doesn't know (or care) whether you're using one git-bash window, multiple windows, git-gui, etc - as far as git is concerned there's no difference between you doing "git add; git commit" in one window, or going "git add" in one, closing that window, shutting down the computer, installing a new video card, making tea, switching ISPs, and then powering it back up and using the GUI to commit.

This applies not just to add and commit but to any sequence of git commands. There's no background process keeping track of the repo or anything, so everything it needs to remember from one command to the next is stored to disk in the .git directory.

ToxicFrog
Apr 26, 2008


Meanwhile, my advisor and I still can't figure out why the git context menu extensions aren't showing up on his machine.

Git on windows is honestly not a fun experience if you aren't comfortable with the command line, even if the context menu entries are working, but I'm not sure how much of that is git and how much is my bias against version control GUIs in general.

ToxicFrog
Apr 26, 2008


crazyfish posted:

Is there a way to determine certain properties about a remote git repository without cloning it? The reason I need to do this is that I have a lot of repositories (well over 100) on which I want to check if HEAD of branch x is tagged within that repo.

git ls-remote --heads <url> <branch> will give you the sha1 of <branch>; you can then use git ls-remote --tags <url> to list all of the tags and see if any of them match the branch head. I don't know if there's a way to do this in a single command, though.

If you know what the tag name should be as well the branch name, you can use filter patterns to just see if that tag exists; check the man page for details.

ToxicFrog
Apr 26, 2008


Dromio posted:

The code was added in 46dde8 but are NOT in the 95c2e96. The diff does not show it being removed in 05c2e96. Why did this happen?

Diff 95c2e96 specifically against 46dde8 and see what it looks like.

At a guess, the merge used all the changes from 4e3c9d2 and dropped the ones from 46dde8e.

ToxicFrog
Apr 26, 2008


Dromio posted:

Yeah, git diff 46dde8 Path\To\TheFileInQuestion does show the changes. But gitk Path\To\TheFileInQuestion does not. Why wouldn't gitk show this?

I'm not sure what the underlying reason is, but in my experience "combined diffs" for merge commits are kind of unintuitive both in gitk and in git diff; furthermore, gitk often has trouble following branching/merging of a single file.

quote:

So that merge was bad... and *I* was the one who did it. How did I mess this up? I'm pretty sure I didn't do something like "select all from theirs". Maybe I was just tired that day.

git merge -s theirs would do this, as would accidentally hitting "use all from theirs" in mergetool. It's also possibly that it auto-merged and got it badly wrong, which is (a) a good reason to use --no-commit when merging and (b) probably worth a bug report if you can reproduce it.

ToxicFrog
Apr 26, 2008


Jam2 posted:

I want to have a better understanding of "PATH" and how to manipulate it. What exactly is the PATH?

$PATH is an environment variable (essentially, a user setting accessible to all programs that you start - although it can have different values for different programs depending on how you start them!) listing all of the directories that it should search for programs, separated by :.

For example, my $PATH at home is /home/ben/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games - meaning that if I enter 'git', it will look first* for /home/ben/bin/git, then /usr/local/sbin/git, then /usr/local/bin/git, and so on. If it can't find git in any of those directories, it errors.

The "different values for different programs" bit is important; it's quite possible for (e.g.) the terminal and Sublime Text to have different values for $PATH depending on your configuration, meaning that one can find git and the other can't. In particular, it's not uncommon to have:

- system-wide $PATH entries, which everyone gets
- user-specific $PATH entries, which all programs you run see
- shell-specific $PATH entries, which apply only to stuff you start through bash (or ksh, or tcsh, or whatever shell you use)

And then, on top of that, if you change $PATH in the shell it'll affect that shell (and programs launched from it) only, not anything else you're running then or in the future.

This is actually very useful at times, since it means you can launch programs with different environment variables to customize their behaviour - but it can be confusing starting out, especially if you - say - don't realize this, open a shell, change $PATH there, and then wonder why your editor isn't seeing those changes. :)

* Ok, strictly speaking it checks aliases, functions and builtins first; the $PATH search happens when it realizes it has no built-in way of handling that command and needs to run a separate program.

ToxicFrog
Apr 26, 2008


Golbez posted:

Not sure which command(s) to do for this, which seems simple, but being a relative git neophyte I'm not sure:

We have a branch. I've since made two commits to it, mainly to store coding ideas, but they didn't pan out, so I want to revert it to where it was two commits ago. I don't want to nuke the more recent commits; I just want to do...

Commit A: Good stuff
Commit B: Bad stuff
Commit C: Worse stuff
Commit D: I want this to have the same state as commit A

How do I do this? I decided to throw hard and hit "git reset --hard" and that appears to have nuked commits B and C from history - there is no commit D, there is simply A. No real harm done, but I had wanted to keep them around as warnings to others. What would have been the proper way of doing this? Checking out A and committing it?

The specific command you're thinking of is git revert, which creates a new commit reverting the changes made by one or more prior commits. The main advantage of this is that it does not involve rewriting history and thus has an entry in the commit log and will work even if you've already pushed the branch or had it pulled by others.

That said, if you're only interested in commit A and not the branch itself, you can (as PiotrLegnica said) merge only A back in or create a new branch from it, and ignore B and C, possibly deleting this branch entirely once A is dealt with.

If you are specifically attached to this branch, revert or reset are pretty much your only options.

ToxicFrog
Apr 26, 2008


yaoi prophet posted:

By 'shelve' do you mean 'take my changes from the version and put them somewhere that's not in a commit' like git stash?

Looking at TFS, "kind of, but", if I understand this correctly. It's like git stash in that it lets you store a changeset for later and roll back working to the last commit, but it's also kind of like committing to a pushed WIP branch in that you can use it to share stashed changes with other people without "actually" committing them.

ToxicFrog
Apr 26, 2008


Jethro posted:

One important caveat: When you perform history editing operations in git, you aren't really editing history (assuming I correctly understand how git works). git is based on explicitly marking certain commits as "interesting" (i.e. by tagging or creating branches). When you rebase, you create new commits and move branches, but the old commits are, technically, still there. They are just no longer "interesting" (since they no longer have a branch pointing to them) so they will get garbage collected eventually.

This is correct. Commits in git are immutable; "history rewrite" commands actually create completely new sets of commits and then rearrange branch pointers to point to the new commits. You can still view the old ones if they've been tagged or are referred to by non-rewritten branch pointers, or by using tools like the reflog. Fully orphaned commits (i.e. not referred to by any tags or branches) will eventually "expire" and be garbage collected.

quote:

In hg, you can always see every changeset. So when you edit history with rebase or histedit (or commit --ammend), you really are removing the changesets as soon as you are done creating the new ones (unless you specify --keep). Re-writing history is seen as dangerous and destructive because, in hg, it is. This is another one of those things that I hadn't fully grasped until I started writing this post.

:gonk:

mobby_6kl posted:

I just added multithreading to my project, but, because I'm a living coding horror, it actually made everything slower despite properly utilizing all 4 cores :negative:. Anyway, what I want to do is roll back to the last commit to work on the more important stuff, while retaining the multithreaded changes for when I want to revisit this later.

Is this what named branches are for? This area of mercurial isn't quite clear to me yet so I'm not too sure what's the correct approach here would be.

In git I would just create a new branch for this (git branch multithreading), rewind master (git reset --hard last-good), and then at some future point, when threading was ready, merge it back into master (git merge multithreading). I'm not clear on how Hg branches are different from git branches beyond "they're different", though.

ToxicFrog
Apr 26, 2008


MononcQc posted:

I would absolutely love it if when using a given open source library or application, I could see that the person in charge keeps on pushing broken and retarded changes to the public, rather than having a pristine history that someone spent days refining to look good and just be surprised by all of the dumb poo poo when I actually get to use it and try to upgrade.

Thing is, with a DVCS, just because there's broken poo poo in the history doesn't mean it was ever publically visible. I commit a lot of things that don't work yet because I still want a record of my work. It just doesn't get pushed to any public repo until it's tested and working.

ToxicFrog
Apr 26, 2008


evensevenone posted:

In git is there a way to have a commit that gets applied after the last commit whatever branch you're on and just sort of follows you around without ever being applied anywhere?

Basically, I have a dev board with some peripherals missing that I need to comment out, and I don't want to crap up our main code with a bunch of #ifndefs just because of this one board I'm using.

Right now I just have a tagged commit that has the needed stuff and when I switch branches I cherry-pick it. Then when I submit my code I just rebase, move that commit to the end, and then reset that branch up a commit. But this seems overly complex and I'm always afraid I'll fat finger something durning a rebase.

Basically, I'd like this one commit to always appear in the working tree but not be part of a branch.

I can't put the affected files in .gitignore because I make other changes to them.

You might want to look into stashes. It's not completely automatic, but git stash will save your index and working tree to a specially named "stash commit", and git stash apply or git stash pop will take a stash (by default the most recent) and apply it to your current working tree and index. pop additionally deletes the saved stash (if it was able to successfully apply it).

This means that your branch switching mechanism now looks like:
code:
## Commit all of your changes that aren't part of this "floating commit"
$ git add some stuff
$ git commit 
## Stash the "floating commit"
$ git stash
## Switch branches
$ git checkout another-feature
## Restore the saved changes
$ git stash pop
Which isn't great but is better than what you're using now, at least.

You could probably set up an alias like git float that does this automatically, too.

ToxicFrog
Apr 26, 2008


GrumpyDoctor posted:

We're using a third-party library in a project that requires a license key to use. The way it works is that you include the license key in the first call into the library, and their license terms require that you actually embed the drat thing in your source code (you can't pull it out of a config file at runtime). So, we've been doing this, and it's been working fine. The problem is that we've gotten a directive from on high to make our codebase publicly available. This presents two problems.

The first is that anyone looking at the source history will be able to see the key. We're using git, and everything I've read about rewriting git history has to do with retroactively blowing away whole files, but this thing doesn't live in its own file and even if it did I'd have to change the build files as well. I'm not even sure what this change would look like - a global, historical, find-and-replace to turn the key into "KEY GOES HERE" or something? Can git do this?

It totally can; the command you're thinking of is git filter-branch. It rewrites history by running a shell command on every commit; make the command something like sed -r -i -e 's/<license key>/XXXXXXXXXXXX/' license.clj and then make sure you don't push the old version of the branch and there you go.

I've used it myself to retroactively remove copyrighted materials I was using for testing from a repo before putting it on github.

quote:

The second problem is how to deal with this going forward. What I've thought of is having a build script that does the aforementioned find-and-replace, but in reverse: to copy the key into the codebase (from an unversioned config file or something), build the project, and then remove it. Does this sound reasonable?

This sounds kind of ugly, to be honest, but I can't think of a better approach given the constraints you're under.

ToxicFrog
Apr 26, 2008


GrumpyDoctor posted:

This is perfect! (But terrifying.)

It's not quite as terrifying as it sounds; git "history rewrites" are non-destructive, in that they create a new, parallel history and leave the original commits intact - so if something goes wrong you can use the reflog to recover the previous state and try again.

quote:

Unfortunately I'm not 100% confident that the key has always resided in the same location, so I'd like to have sed work on the whole codebase. Do you think that this would be tractable for a ~15kloc project? If so I'll go dig up some incantation to do that. (I guess you have to pipe find into sed? I don't do this kind of thing ever.)

You'd probably want find -exec, say something like:

code:
find . -name '*.clj' -or -name '*.lua' -exec sed -i 's/<key>/XXXX/g' '{}' '+'
That finds all files with the extension .clj or .lua, and runs sed on them to edit them in-place (-i) and replace <key> with XXXX. The '{}' is replaced with a list of found files. The '+' tells find to replace the '{}' with a list and run sed on as many files as possible (whereas ';', as in Plorkyeran's example, will run one sed per file and may be slower).

ToxicFrog
Apr 26, 2008


Volmarias posted:

Yeah, we've got a commit message template which has both a problem section and a solution section. Obviously, if you're adding a new feature you can probably reword this a little, but you have to go out of your way to make a bad message like the one evensevenone mentions, and you'd probably get ripped in the code review.

Problem: we don't have a turnip twaddler feature.
Solution: we have a turnip twaddler feature now.

34 files changed, 4207 insertions(+), 987 deletions(-)

If you have code reviews this hopefully doesn't happen, though.

ToxicFrog
Apr 26, 2008


oiseaux morts 1994 posted:

Seems mental, especially if you wanted to edit a commit way back, you'd create a massive chain of copies of your original commits. But I suppose if the old commits are garbage collected anyway, it's a viable method? Sorry, I appreciate this is really pedantic but stuff like this just sets off my goony autism like nothing else

That is exactly how it works.

Bear in mind that commits themselves are tiny, and the file data they point to is in content addressed storage and thus deduplicated. So if the commit contents are mostly the same the space cost is minimal even before garbage collection.

ToxicFrog
Apr 26, 2008


NoDamage posted:

What's the easiest way to view the differences between two git branches using a GUI?

Essentially, I want to be able to browse through the results of
code:
git diff master..branch
in some kind of tool that shows me all the files that changed, and then lets me click on each file and see the diffs between them.
code:
git difftool master..branch
doesn't really work since it opens up each file individually, instead of showing me all the diffs at once. Do I need to configure something?

gitk can do this; open it up, select one branch, then right-click on the other and "diff this->selected" (or vice versa).

I think there's also a way to get it to pass all the filepairs to difftool at once (if your difftool supports that), but I don't remember where I read it.

ToxicFrog
Apr 26, 2008


Git isn't even consistent about that, either; git clean, unlike git checkout, really does only have one purpose, the removal of untracked files and directories - but by default it won't do anything, requiring some combination of -d and -f to actually do what you just told it to.

I love git, but holy poo poo is its UI a trainwreck.

ToxicFrog
Apr 26, 2008


chippy posted:

In Git, is there a quick/easy way of merging a branch into master, and if there are any conflicts, to automatically take the version of the file from the branch I'm merging in?

Basically, I need the contents of the other branch to become the new master branch, but retaining commit history etc. Is strategy=ours what I need here?

You're asking for two different things here.

"merge a branch into master, and if there are any conflicts, automatically take that branch's version": git checkout master && git merge -X theirs other-branch. The -X theirs tells the default merge strategy to proceed normally except when conflicts are detected, which will always be resolved in favour of the branch you're merging in.

This is not the same as "I need the contents of the other branch to become the new master branch", which implies that you want to throw away all changes made by master including non-conflicting ones. For that, the natural thing to do would be to use the 'theirs' merge strategy (-s theirs, not to be confused with the 'theirs' merge option -X theirs) -- but it was removed several versions ago for some reason. The git devs recommend using git reset instead, but that'll throw away the history you want to keep.

Probably the easiest workaround is something like:
code:
git checkout other-branch
# merge master into this branch and throw away the changes
git merge -s ours master
# fiddle the branch heads so it looks like this branch got merged into master instead
git branch -f master
git reset --hard HEAD^

aerique posted:

Who here is using Git in a larger organization with more than, say, 50 or 100 developers? Do you use something like GitLab for managing users and repositories?

I am (both here and at my previous job), but probably not in a way that helps you. In both places we use Perforce as the backend and then individual developers use git locally - at the previous job using git-p4, and here using a custom git<->p4 bridge that also integrates with stuff like our code review tools.

It's actually quite nice, but it also completely avoids answering the question of "how do you scale git to a large organization" by treating it as a single-developer productivity tool instead.

Adbot
ADBOT LOVES YOU

ToxicFrog
Apr 26, 2008


Dylan16807 posted:

Apparently the 'theirs' merge strategy was removed because they don't like that workflow. If you want to keep that unused history you're supposed to stick it in a different branch: http://marc.info/?l=git&m=121637513604413&w=2

But if you want to do it anyway, how about this for a workaround:
code:
git checkout master
git merge --no-commit other-branch
git checkout other-branch . #blow away all differences
git commit

I almost suggested that, actually, but it doesn't handle deletions properly - if master has files A B C, and other-branch adds D and deletes B, those commands may result in you having A B C D rather than A C D, depending on how the initial merge went.

HardDisk posted:

Git works pretty well for text files, as every programmer here that uses it knows, but is there any other VCSs more suitable for other types of files, say images or 3D models?

That's part of why we use Perforce.

There's also git-annex and git-media, neither of which I've used.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply