Sometimes changes required for mods are due to Minecraft itself changing, and other times they're from MCP and Forge changing.
First of all you have to keep in mind that Mojang obfuscates Minecraft, so when it's decompiled, the MCP team has to go about the arduous task of determining what the entirely random function and variable names mean. Reverse engineering can be very difficult and time-consuming, yet they have to do this for every version. I'm sure they have tools to help identify code fragments which haven't changed (or changed much) based on previous efforts. But any time new code is added by Mojang, it requires them to go through it line by line and figure out what it does. With Minecraft 1.7, for example, they say up to a third of the code has changed. It's a major undertaking, and it's why we should all always be very grateful to the MCP team, without which we wouldn't even be here right now.
As you can imagine, there's not a lot of point in deobfuscating and reverse-engineering the snapshots and preleases, because code is still going to change, as are the obfuscated names. In some cases it might help them get a jump on things, but in other cases it's just doing the same work twice.
But the obfuscation has an even deeper implication for modding: coremods. Sometimes you need to change the way Minecraft itself works. Maybe you need to add a hook to something to interact with it in your own code, or you want to change entire native functionality. You could do this through a jar mod, where you just compile and reobfuscate your code and drop it in the jar, but this really isn't recommended anymore if you want to be compatible with as many other mods as possible. Coremods on the other hand are able to intercept the loading of Minecraft classes, and allow you to either replace the entire class (not really recommended), or parse through it and add/remove/replace the raw Java bytecode (the most recommended method). Well, when you're developing your mods, everything is deobfuscated, including Minecraft. These easily-recognizable names are the ones you search for to modify during development. However, when your mod is compiled, reobfuscated, and running in a regular Minecraft client, Minecraft itself is obviously obfuscated now as well. This means in your coremod you have to be intercepting the obfuscated class, method, and variable names you intend to replace. You never know what the obfuscated names will be between versions, and they usually change. There's also the possibility that the code you're modifying could have changed, which might mean you have to change how you're parsing for it. Overall, it means compiling your coremod for essentially every version of Minecraft you want to support.
As for Minecraft itself, you have other major internal changes. Between 1.2.5 and 1.3, for example, it was pretty big. The client and server were "merged" so that even singleplayer games ran on an internal server. Beforehand, you had to write two separate mods. Afterward, you wrote just one. But obviously this had major implications from a programming point of view. All of your code was now always running in two places at once. The "proxy" system was implemented so that you could still have server and client-specific code, because there will still be times when you only want certain code to execute on one or the other. There were significant other differences as well, from everything on how you registered blocks, to recipes, to doing custom rendering, entities, key bindings, etc. Due to the effort required, some mods never updated again until Minecraft 1.4.x.
When Minecraft went from 1.4.7 to 1.5, textures were a major change. Before that you could have sprite sheets, but afterward every texture had to be in a separate file. Minecraft now stitched these together internally, handling all UV coordinates itself. There was also a new directory structure that they were supposed to be stored in. This all resulted in code-based changes in how you loaded and assigned your textures as well. Very tedious work, particularly for larger mods.
Minecraft 1.5.x to 1.6 was more changes in textures. They were in a different directory now. Differences in deobfuscated method names also resulted in changing how you specified your textures. Also, the way that Forge handled mod initialization changed. I'm sure there were other differences, some significant depending on what your mod did, but these are the two biggest things I deal with when maintaining two of my mods between both.
I could go on and on, and there were way more changes with all of these version differences than I'm mentioning, but I think you can start to get an idea. Forge isn't one central API which all mods can interact with; mods use native Minecraft methods to interact with the game. The introduction of SRG names with MCP was a huge improvement, where MCP began trying to map the same function names across as many similar versions of the game as possible, so that regular mods could likely work without recompiling. But when Mojang changes something significant, mods typically have to change as well. Sometimes it's huge changes, other times not so bad.
Another major upcoming change is apparently doing away with block IDs, using labels instead. This would be a significant improvement for both modders and players, since block ID conflicts have always been a bane. But internally this will have huge ramifications for developers.
Anyhoo, unfortunately, with 1.7, it's a big one. Eventually things will get caught up, and I'm sure we'll get to use some amazing mods along with all the great new features Mojang added. But in the meantime, we just have to wait, while the MCP and Forge teams do their magic.